Sự khác biệt giữa khung kiểm tra đơn vị ScalaTest và Scala Specs là gì?


121

Cả hai đều là khung kiểm tra đơn vị có khả năng BDD (Behavior Driven Development) dành cho Scala được viết bằng Scala. Và các Thông số kỹ thuật được xây dựng cũng có thể liên quan đến khung ScalaTest . Nhưng những gì mà Specs cung cấp ScalaTest không? Sự khác biệt là gì?


1
Tôi không tin rằng việc nói Specs được xây dựng dựa trên ScalaTest là chính xác. Lưu ý rằng sự phụ thuộc trong pom là tùy chọn. Mặc dù vậy, các thông số kỹ thuật có khả năng chạy các thông số kỹ thuật của nó như một bộ ScalaTest.
Geoff Reedy

scalatest cung cấp scalatestplus với hỗ trợ cụ thể cho một số lib. nó có thể là thú vị. chẳng hạn, họ có scalatestplus cho khung chơi
pedrorijo91

Câu trả lời:


172

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'sFeatureSpecVí 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 isDirectoryvà đả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 directoryhoặ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ọcSpecificationvề 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 setUptearDownphổ 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


6
Đối với tôi, khả năng đọc của scalatest là một điểm chiến thắng lớn so với thông số scala.
nemoo

49

Sự khác biệt chính là (chủ yếu là từ quan điểm thông số kỹ thuật :-)):

  • ScalaTest cung cấp nhiều "kiểu thử nghiệm" hơn là thông số kỹ thuật (bạn có thể truy cập từng dấu đầu dòng trên trang bắt đầu nhanh để có cái nhìn chi tiết về từng kiểu)

  • ScalaTest và thông số kỹ thuật có một bộ đối sánh khác nhau. Bạn có thể so sánh chúng ở đây cho ScalaTest và đây để biết thông số kỹ thuật. Về mặt đó, thông số kỹ thuật có rất nhiều tính năng nhỏ mà bạn có thể thích khi viết thông số kỹ thuật của mình: trình khớp xml, thành phần đối sánh (một cách dễ dàng để sử dụng lại trình khớp bằng cách biến đổi chúng), lỗi chính xác, sự khác biệt chi tiết cho các chuỗi dài, .. .

  • Mockito đã được hỗ trợ BDD tốt về thông số kỹ thuật: Mockito

  • thông số kỹ thuật có DataTables cho phép nhóm nhiều ví dụ nhỏ trong một loại bảng (nếu bạn có thể chấp nhận các toán tử được sử dụng làm dấu phân cách bảng)

  • Trong thông số kỹ thuật, bạn có thể xác định các ví dụ được lồng vào nhau dưới dạng libidum và tự động làm sạch ở mọi cấp độ

Đây chắc chắn là một so sánh rất phiến diện và thiên lệch và còn tồn tại nhiều khác biệt khác (và các thư viện vẫn đang phát triển, ...).

Vào cuối ngày, tôi nghĩ rằng nó thực sự phụ thuộc vào phong cách thử nghiệm / chỉ định của bạn. Nếu nó đơn giản (cấu trúc đặc tả đơn giản, thiết lập, kỳ vọng, ...) thì cả hai thư viện sẽ xuất hiện rất giống nhau. Nếu không, cả hai đều có trách nhiệm của họ về cách mọi thứ nên được thực hiện. Ví dụ cuối cùng về điều này, bạn có thể xem cách gắn thẻ: trong ScalaTest và trong thông số kỹ thuật .

Tôi hi vọng cái này giúp được.


Có thể cập nhật điều này để bao gồm thông số kỹ thuật2 không? :)
Joffer

5

Theo như tôi biết, ngoại trừ một vài tính năng chuyên biệt cao, nó phụ thuộc vào sở thích cá nhân theo phong cách.


2

Hỗ trợ IDE có thể là một điểm khác

Tôi đã cố gắng để Thông số kỹ thuật hoạt động với Eclipse thông qua JUnit và tôi nhận thấy giải pháp chính thức là một chút "hacky". Thiết lập thông số kỹ thuật: http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse

Sự tích hợp của ScalaTest (cũng thông qua JUnit) có vẻ ít hacky hơn một chút. Tuy nhiên, tôi không có bất kỳ cái nào trong số chúng hoạt động tốt như JUnit và Java.

Thiết lập ScalaTest: http://groups.google.com/group/scalatest-users/web/running-scalatest-from-eclipse


Tôi nhận được 404 cho liên kết ScalaTest đó ngay bây giờ. Hãy thử scalatest.org/user_guide/using_junit_runner
DNA

0

Nếu một yếu tố quyết định là thời gian biên dịch, thì khả năng mở rộng có vẻ hoạt động tốt hơn.

Chúng tôi hiện đang sử dụng specs2 trong dự án của mình, nhưng gặp phải thời gian biên dịch chậm trong các thử nghiệm. Tôi vừa hoàn thành POC khi chuyển sang mở rộng nhất và thấy thời gian biên dịch giảm xuống khoảng 0,82 chỉ bằng cách chuyển đổi 2 khung công tác trong một số nguồn của chúng tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.