Specs và ScalaTest đều là những công cụ tốt với những người dùng hài lòng, nhưng chúng khác nhau theo một số cách. Bạn có thể sẽ muốn chọn một cái làm công cụ kiểm tra chính của mình trong Scala, nhưng không cần phải bỏ cái kia vì bạn có thể sử dụng các phần của cả hai. Nếu bạn thích ScalaTest'sFeatureSpec
Ví dụ: cú pháp và cú pháp thông số kỹ thuật của Mockito, bạn có thể đặt cả hai tệp jar vào đường dẫn phân nhánh của mình và sử dụng cả hai cùng một lúc. Ở đây tôi sẽ thử và nắm bắt những khác biệt triết lý thiết kế chính mà tôi đã nhận thấy giữa thông số kỹ thuật và ScalaTest.
Có lẽ sự khác biệt triết học chính giữa các công cụ là thông số kỹ thuật được thiết kế cho Phát triển theo hướng hành vi (BDD), trong khi ScalaTest thì tổng quát hơn. ScalaTest cung cấp các đặc điểm mà bạn có thể kết hợp với nhau để có được hành vi mà bạn thích trong các lớp thử nghiệm của mình, bao gồm cả BDD và bạn cũng có thể dễ dàng xác định hành vi của riêng mình nếu bạn muốn điều gì đó khác biệt.
Hỗ trợ ScalaTest BDD qua nó Spec
, FeatureSpec
, WordSpec
, FlatSpec
, và GivenWhenThen
đặc điểm, và cũng có những đặc điểm mà bạn có thể kết hợp để có được một cú pháp khớp tốt đẹp. Nếu bạn thích "should", bạn kết hợp ShouldMatchers. Nếu bạn thích "phải", bạn trộn vào MustMatchers
. Nhưng nếu bạn thích BDD nhưng không thích cú pháp so khớp, bạn có thể chỉ sử dụng một trong các đặc điểm Spec của ScalaTest mà không trộn lẫn vào một đặc điểm so khớp. Specs có một lớp Đặc tả mà bạn mở rộng và bạn phải sử dụng từ "phải" trong các biểu thức đối sánh của mình. Một sự khác biệt lớn về mặt triết học có thể thấy rõ ở đây là ScalaTest mang đến cho bạn nhiều sự lựa chọn hơn. Để điều hướng không gian lựa chọn này dễ dàng hơn, tôi cung cấp một cây quyết định ở đây:
http://www.scalatest.org/quick_start
Cú pháp đối sánh cũng khác nhau giữa ScalaTest và thông số kỹ thuật. Trong ScalaTest, tôi đã cố gắng xem tôi có thể đi bao xa với ký hiệu toán tử và kết thúc với các biểu thức so khớp đọc rất giống câu tiếng Anh, với khoảng cách giữa các từ. Cú pháp đối sánh thông số chạy các từ với nhau nhiều hơn với trường hợp lạc đà.
Thông số kỹ thuật có nhiều đối sánh hơn ScalaTest và điều đó tôi nghĩ phản ánh sự khác biệt trong quan điểm thiết kế. Tôi thực sự đã cắt có lẽ 2/3 cú pháp so khớp mà tôi đã xây dựng và cân nhắc để phát hành. Tôi sẽ thêm nhiều người so khớp hơn trong các bản phát hành trong tương lai, nhưng muốn chắc chắn rằng tôi biết người dùng thực sự muốn thứ gì đó trước khi tôi thêm nó. Tuy nhiên, các trình đối sánh của ScalaTest bao gồm cú pháp đối sánh thuộc tính động sẽ chiếm một phần trong số đó. Ví dụ trong Specs, bạn có thể viết trên java.io.File
:
file must beDirectory
Điều này sẽ gọi isDirectory
và đảm bảo rằng nó là đúng. ScalaTest hiện không có bất kỳ đối sánh đặc biệt nào java.io.Files
, nhưng trong ScalaTest, bạn chỉ có thể sử dụng kiểm tra động như sau:
file must be a ('directory)
Bất cứ khi nào bạn chuyển một biểu tượng vào sau be
, nó sẽ sử dụng sự phản chiếu để tìm kiếm (trong trường hợp này) một phương thức hoặc trường có tên directory
hoặc một phương thức được đặt tên isDirectory
. Cũng có một cách để làm cho điều này tĩnh, bằng cách xác định a BePropertyMatcher
(thường chỉ yêu cầu 2 hoặc 3 dòng mã). Vì vậy, về cơ bản trong ScalaTest, tôi cố gắng cung cấp nhiều chức năng hơn với ít API hơn.
Một sự khác biệt về thái độ thiết kế chung khác giữa thông số kỹ thuật và ScalaTest liên quan đến chuyển đổi ngầm định. Theo mặc định, bạn chỉ nhận được một chuyển đổi ngầm định khi bạn sử dụng ScalaTest, là chuyển đổi đặt ===
nhà điều hành vào mọi thứ. (Nếu cần, bạn có thể "tắt" chuyển đổi ngầm này bằng một dòng mã. Lý do duy nhất bạn cần làm điều đó là nếu bạn đang cố gắng kiểm tra thứ gì đó có===
toán tử và bạn nhận được xung đột. ) ScalaTest xác định nhiều chuyển đổi ngầm định khác, nhưng để sử dụng chúng, bạn cần phải "mời" chúng vào mã của mình một cách rõ ràng bằng cách trộn lẫn một đặc điểm hoặc thực hiện nhập. Khi bạn mở rộng lớp họcSpecification
về thông số kỹ thuật, tôi nghĩ rằng bạn nhận được hàng tá chuyển đổi ngầm theo mặc định. Tôi không chắc điều đó sẽ quan trọng như thế nào trong thực tế, nhưng tôi nghĩ mọi người sẽ muốn kiểm tra mã sử dụng hàm ý của riêng họ và đôi khi có thể có xung đột giữa hàm ý của khung kiểm tra và mã sản xuất. Khi điều đó xảy ra, tôi nghĩ có thể dễ dàng giải quyết vấn đề trong ScalaTest hơn là thông số kỹ thuật.
Một sự khác biệt khác trong quan điểm thiết kế mà tôi nhận thấy là sự thoải mái với người vận hành. Một mục tiêu của tôi là bất kỳ lập trình viên nào nhìn vào mã thử nghiệm của người khác sử dụng ScalaTest sẽ có thể đoán ý nghĩa của nó mà không cần tra cứu bất cứ điều gì trong tài liệu ScalaTest. Tôi muốn mã khách hàng ScalaTest được xóa rõ ràng. Một cách mà mục tiêu thể hiện chính là ScalaTest rất thận trọng về các toán tử. Tôi chỉ định nghĩa năm toán tử trong ScalaTest:
===
, có nghĩa là bằng
>
, có nghĩa là lớn hơn
<
, ít hơn
>=
, lớn hơn hoặc bằng
<=
, nhỏ hơn hoặc bằng.
Đó là nó. Vì vậy, những điều này khá giống với ý nghĩa. Nếu bạn thấy mã của người khác:
result should be <= 7
Tôi hy vọng rằng bạn sẽ không cần phải chạy đến tài liệu API để đoán điều đó <=
có nghĩa là gì. Ngược lại, thông số kỹ thuật tự do hơn nhiều với các nhà khai thác. Không có gì sai với điều đó, nhưng nó là một sự khác biệt. Các nhà khai thác có thể làm cho mã hơn súc tích, nhưng sự cân bằng là bạn có thể phải chạy đến các tài liệu khi bạn tìm thấy những thứ như ->-
, >>
, |
, |>
, !
, hoặc ^^^
(mà tất cả đều có ý nghĩa đặc biệt trong Specs) trong mã thử nghiệm của đồng nghiệp của bạn.
Một khác biệt triết học khác là tôi đã thử và làm cho nó dễ dàng hơn một chút trong ScalaTest để sử dụng một kiểu chức năng khi bạn cần chia sẻ một vật cố định, trong khi Thông số kỹ thuật theo mặc định tiếp tục truyền thống của cách tiếp cận setUp
và tearDown
phổ biến bởi JUnit, trong đó bạn chỉ định lại các giao diện trước mỗi bài kiểm tra. Tuy nhiên nếu bạn muốn kiểm tra theo cách đó, nó cũng rất dễ dàng trong ScalaTest. Bạn chỉ cần trộn vào BeforeAndAfter
đặc điểm.
Để biết thêm thông tin chi tiết về ScalaTest, bạn có thể xem bài thuyết trình "Nâng cao trình độ với ScalaTest" mà tôi đã trình bày tại hội nghị Devoxx năm 2009 tại đây:
http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about