Là một bài kiểm tra Đơn vị được coi là dễ vỡ nếu nó thất bại khi logic kinh doanh thay đổi?


27

Xin vui lòng xem mã dưới đây; nó kiểm tra xem một người có Giới tính nữ có đủ điều kiện nhận ưu đãi1 không:

[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
    var personId = Guid.NewGuid();
    var gender = "F";
    var person = new Person(personId, gender);

    var id = Guid.NewGuid();
    var offer1 = new Offer1(id,"Offer1");
    Assert.False(offer1.IsEligible(person));
}

Bài kiểm tra đơn vị này thành công. Tuy nhiên, nó sẽ thất bại nếu 'Offer1' được cung cấp cho phái nữ trong tương lai.

Có thể chấp nhận được không - nếu logic nghiệp vụ xung quanh cung cấp 1 thay đổi thì kiểm tra đơn vị phải thay đổi. Xin lưu ý rằng trong một số trường hợp (đối với một số ưu đãi) logic nghiệp vụ được thay đổi trong cơ sở dữ liệu như sau:

update Offers set Gender='M' where offer=1;

và trong một số trường hợp trong mô hình miền như thế này:

if (Gender=Gender.Male)
{
  //do something
}

Cũng xin lưu ý rằng trong một số trường hợp, logic miền phía sau cung cấp thay đổi thường xuyên và trong một số trường hợp thì không.


2
Suy nghĩ từ một góc độ khác: Bạn có muốn có các bài kiểm tra không thất bại khi bạn thay đổi logic trong hệ thống theo bài kiểm tra không?
Fabio

Câu trả lời:


77

Điều này không dễ vỡ theo nghĩa thông thường. Một thử nghiệm đơn vị được coi là dễ vỡ nếu nó bị hỏng do thay đổi triển khai không ảnh hưởng đến hành vi được thử nghiệm. Nhưng nếu logic kinh doanh tự thay đổi, thì một bài kiểm tra logic này được cho là sẽ phá vỡ.

Điều đó nói rằng, nếu logic kinh doanh thực sự thay đổi thường xuyên, có lẽ không phù hợp để mã hóa các kỳ vọng vào các bài kiểm tra đơn vị. Thay vào đó, bạn có thể kiểm tra xem các cấu hình trong cơ sở dữ liệu có ảnh hưởng đến các ưu đãi như mong đợi hay không.

Tên của bài kiểm tra Returns False When Given A Person With A Gender Of Femalekhông mô tả một quy tắc kinh doanh. Một quy tắc kinh doanh sẽ là một cái gì đó như Offers Applicable to M should not be applied to persons of gender F.

Vì vậy, bạn có thể viết một bài kiểm tra xác nhận rằng nếu một đề nghị được xác định là chỉ áp dụng cho người loại M, thì một người loại F sẽ không được chỉ định là đủ điều kiện cho nó. Thử nghiệm này sẽ đảm bảo logic hoạt động ngay cả khi cấu hình của các ưu đãi cụ thể thay đổi.


@JaquesB, sau đó nó sẽ không phải là một bài kiểm tra đơn vị? hoặc nó sẽ? Tôi tin rằng nó sẽ là một thử nghiệm tích hợp nếu cơ sở dữ liệu có liên quan. Có đúng không? Bạn đang nói không sử dụng các bài kiểm tra đơn vị nếu logic kinh doanh thay đổi nhiều?
w0051977

@ w0051977: Phụ thuộc vào cách bạn viết bài kiểm tra. Nếu thử nghiệm bao gồm thực sự thay đổi thay đổi một cái gì đó trong cơ sở dữ liệu, thì đó sẽ là thử nghiệm tích hợp.
JacquesB

3
@ w0051977 ý tưởng tốt hơn - không có kho lưu trữ là một phụ thuộc của thành phần chịu trách nhiệm thực hiện các quy tắc kinh doanh. Có một dàn nhạc cấp cao hơn gọi kho lưu trữ và sau đó gọi các quy tắc kinh doanh. Bây giờ bạn có thể đơn vị kiểm tra các quy tắc kinh doanh trong sự cô lập.
Ant P

5
@ w0051977 tất nhiên là thế - kiểm tra chỉ định hành vi. Nếu các quy tắc chi phối hành vi của một thay đổi thành phần, thì các thử nghiệm phải thay đổi để phản ánh sự thay đổi trong hành vi. Những gì không cần thay đổi là các thử nghiệm chỉ định các hành vi khác với những gì đang thay đổi. Nếu hành vi được xác định bởi cơ sở dữ liệu, thì một thử nghiệm bao gồm một số mã khác vốn không liên quan và không cần phải thay đổi trừ khi logic cơ sở dữ liệu đó nằm trong phạm vi của thử nghiệm. Phạm vi đó là để bạn xác định và ngữ nghĩa của việc kiểm tra đơn vị hay kiểm tra tích hợp không thực sự quan trọng.
Ant P

3
@ w0051977 mở rộng ý tưởng này phần nào, nếu logic kinh doanh thay đổi hoặc lỗi được khắc phục và các bài kiểm tra không cần điều chỉnh, đó là dấu hiệu cho thấy các bài kiểm tra không bao gồm đủ trường hợp và thường nên được mở rộng.
Morgen

14

Khi thuộc tính được xác định trong cơ sở dữ liệu sản xuất (hoặc bản sao để thử nghiệm), đây không phải là thử nghiệm đơn vị . Một bài kiểm tra đơn vị kiểm tra một đơn vị công việc và không yêu cầu một trạng thái bên ngoài cụ thể để làm việc. Giả định Offer1này được xác định trong cơ sở dữ liệu là ưu đãi chỉ dành cho nam giới. Đó là trạng thái bên ngoài. Vì vậy, đây là nhiều hơn một thử nghiệm tích hợp , cụ thể là một thử nghiệm hệ thống hoặc chấp nhận . Lưu ý rằng các bài kiểm tra chấp nhận thường không được viết kịch bản (không chạy trong khung kiểm tra mà do con người thực hiện thủ công).

Khi thuộc tính được xác định trong mô hình miền với một ifcâu lệnh, cùng một bài kiểm tra là một bài kiểm tra đơn vị. Và nó có thể giòn. Nhưng vấn đề thực sự là mã dễ vỡ. Theo nguyên tắc chung, mã của bạn sẽ linh hoạt hơn nếu hành vi kinh doanh có thể định cấu hình thay vì mã hóa cứng. Bởi vì việc triển khai vội vàng để sửa một lỗi mã hóa nhỏ nên rất hiếm. Nhưng một yêu cầu kinh doanh thay đổi mà không cần thông báo chỉ là thứ ba (điều gì đó xảy ra hàng tuần).

Bạn có thể đang sử dụng khung kiểm tra đơn vị để chạy thử nghiệm. Nhưng khung kiểm tra đơn vị không giới hạn trong việc chạy thử nghiệm đơn vị. Họ có thể và thực hiện chạy thử nghiệm tích hợp là tốt.

Nếu bạn đang viết một bài kiểm tra đơn vị, bạn sẽ tạo cả hai personoffer1từ đầu mà không phụ thuộc vào trạng thái cơ sở dữ liệu. Cái gì đó như

[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
    var personId = Guid.NewGuid();
    var gender = "F";
    var person = new Person(personId, gender);

    var id = Guid.NewGuid();
    var offer1 = new Offer1(id, "ReturnsFalseWhenGivenAPersonWithAGenderOfFemale");
    offer1.markLimitedToGender("M");

    Assert.False(offer1.IsEligible(person));
}

Lưu ý rằng điều này không thay đổi dựa trên logic kinh doanh. Nó không khẳng định rằng offer1từ chối con cái. Nó đang làm cho offer1loại đề nghị từ chối phụ nữ.

Bạn có thể tạo và cấu hình cơ sở dữ liệu như một phần của bài kiểm tra. Trong C #, sử dụng NUnit hoặc trong JUnit của Java, bạn sẽ thiết lập cơ sở dữ liệu theo một Setupphương thức. Có lẽ khung kiểm tra của bạn có một khái niệm tương tự. Trong phương thức đó, bạn có thể chèn các bản ghi vào cơ sở dữ liệu bằng SQL.

Nếu bạn khó viết mã thay thế cơ sở dữ liệu kiểm tra cho cơ sở dữ liệu sản xuất, thì đó có vẻ như là một điểm yếu kiểm tra trong ứng dụng của bạn. Để thử nghiệm, sẽ tốt hơn nếu sử dụng một cái gì đó như tiêm phụ thuộc cho phép thay thế. Sau đó, bạn có thể viết các bài kiểm tra độc lập với các quy tắc kinh doanh hiện tại.

Một lợi ích phụ của việc này là thường dễ dàng hơn cho chủ doanh nghiệp (không nhất thiết là chủ sở hữu công ty, giống như người chịu trách nhiệm về sản phẩm này trong hệ thống phân cấp doanh nghiệp) để định cấu hình trực tiếp các quy tắc kinh doanh. Bởi vì nếu bạn có loại khung kỹ thuật này, thật dễ dàng cho phép chủ doanh nghiệp sử dụng giao diện người dùng (UI) để định cấu hình ưu đãi. Chủ doanh nghiệp sẽ chọn giới hạn trong giao diện người dùng và nó sẽ thực hiện markLimitedToGender("M")cuộc gọi. Sau đó, khi đề nghị được duy trì cho cơ sở dữ liệu, nó sẽ lưu trữ này. Nhưng bạn sẽ không cần phải lưu trữ đề nghị để sử dụng nó. Vì vậy, các thử nghiệm của bạn có thể tạo và định cấu hình một đề nghị không tồn tại trong cơ sở dữ liệu.

Trong hệ thống của bạn như được mô tả, chủ doanh nghiệp sẽ phải gửi yêu cầu cho nhóm kỹ thuật, tổ chức này sẽ đưa ra SQL phù hợp và cập nhật các bài kiểm tra. Hoặc nhóm kỹ thuật phải chỉnh sửa mã của bạn và kiểm tra (hoặc kiểm tra sau đó mã). Đó có vẻ là một cách tiếp cận khá nặng nề. Bạn có thể làm được. Nhưng phần mềm của bạn (không chỉ là thử nghiệm của bạn) sẽ ít giòn hơn nếu bạn không phải làm như vậy.

TL; DR : bạn có thể viết các bài kiểm tra như thế này, nhưng bạn có thể viết phần mềm của mình tốt hơn để bạn không phải làm như vậy.


Tôi công cụ tự do để cải thiện một số chi tiết nhỏ trong câu trả lời của bạn. Vui lòng kiểm tra nếu tôi có ý định của bạn đúng.
Doc Brown

Không có dấu hiệu nào trong bài viết gốc rằng cơ sở dữ liệu có liên quan. Vì vậy, tuyên bố rằng nó giả định rằng Offer1 đã có trong cơ sở dữ liệu là kỳ quái.
Winston Ewert

2
@WinstonEwert: có một chỉ dẫn rõ ràng, bạn phải đọc kỹ câu hỏi hơn. Tôi đã không nhận ra nó ngay từ lần đọc đầu tiên, nhưng đó thực sự là những gì OP đang nói đến.
Doc Brown

@ mdfst13, tôi xin lỗi tôi đã bỏ lỡ điều đó. Tuy nhiên, những gì OP đang nói là các điều kiện đôi khi nằm trong cơ sở dữ liệu và đôi khi trong mô hình miền. Câu trả lời của bạn là hoàn toàn tốt cho trường hợp đầu tiên, và không thường xuyên trong lần thứ hai. Nếu bạn sẽ chỉnh sửa câu trả lời của mình để làm rõ điểm đó, tôi sẽ xóa phần trích dẫn vội vàng của tôi.
Winston Ewert
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.