Bài kiểm tra đơn vị: xác nhận hoãn lại với Linq


18

Có ổn không khi thêm các xác nhận hoãn lại như thế này

var actualKittens = actualKittens.Select(kitten => {
    Assert.IsСute(kitten);
    return kitten
});

Tại sao? Vì vậy, tôi có thể lặp lại chỉ một lần ngay cả với các câu lệnh mong muốn bộ sưu tập được cụ thể hóa:

CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

Và cũng có thể không chỉ là Chọn mà là một phương thức với iterator được xác định và có rất nhiều kiểm tra và logic (ví dụ: một số đếm và lọc).

Hạt giống của sự nghi ngờ là sự phức tạp của việc đọc và gỡ lỗi mã như vậy trong trường hợp thử nghiệm thất bại.


1
Tôi sẽ không dựa vào điều này để thử nghiệm nhưng đôi khi vẫn ổn khi thực hiện điều này trong mã sản xuất nếu không có giải pháp nào tốt hơn. Bạn có thể làm cho mình một chức năng trợ giúp sequence.WithSideEffect(item => Assert.IsCute(item))để làm cho nó sạch hơn.
usr

@usr Hình như bạn đã bắt được lỗ hổng quan trọng của cách đó - Hiệu ứng phụ từ một trình vòng lặp.
SerG

Bạn vẫn không phải lặp lại hai lần, một lần để tạo danh sách và một lần nữa để so sánh nó với expectedKittens? Bạn vừa ẩn các lần lặp đằng sau các cuộc gọi phương thức.
IllusiveBrian

@IllusiveBrian Theo nghĩa này, trong ví dụ, có. Nó vẫn còn ít hơn với bổ sung .All().
SerG

Câu trả lời:


37

Có ổn không khi thêm các xác nhận hoãn lại như thế này [..]

Không , không phải vậy. Tại sao? Bởi vì nếu bạn vì bất kỳ lý do gì, hãy loại bỏ xác nhận thứ hai, thử nghiệm vẫn sẽ chuyển sang màu xanh và bạn sẽ nghĩ rằng nó vẫn hoạt động nhưng không phải vì bộ sưu tập sẽ không được liệt kê. Nếu bạn có hai hoặc nhiều xác nhận độc lập, họ sẽ tiếp tục thực hiện công việc của mình ngay cả khi bạn vô hiệu hóa một trong số chúng.

Hãy xem xét sự kết hợp này:

Assert.IsTrue(actualKittens.All(x => x.IsCute());
CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

Bây giờ ngay cả khi bạn vô hiệu hóa hoặc loại bỏ một trong những khẳng định thì người kia vẫn sẽ thực hiện công việc của mình. Ngoài ra nếu bạn quên hiện thực hóa bộ sưu tập thì có thể mất nhiều thời gian hơn để chạy nhưng nó vẫn hoạt động. Kiểm tra độc lập là mạnh mẽ hơn và đáng tin cậy.

Ngoài ra còn có thứ hai không . Tôi không chắc các khung công tác khác xử lý nó như thế nào nhưng nếu bạn đang sử dụng nền tảng MS Test thì bạn sẽ không biết thử nghiệm nào thất bại. Nếu bạn nhấp đúp vào bài kiểm tra thất bại, nó sẽ cho bạn thấy CollectionAssertlà thất bại nhưng thực tế, đó là lỗi được lồng Assertvà nó sẽ cực kỳ khó gỡ lỗi. Đây là một ví dụ:

    [TestMethod]
    public void TestMethod()
    {
        var numbers = new[] { 1, 2, 3 }.Select(x =>
        {
            Assert.Fail("Wrong number.");
            return x;
        });

        // This will fail and you won't be sure why.
        CollectionAssert.AreEqual(new[] { 1, 2, 3 }, numbers.ToList()); 

    }

Điều này có nghĩa là thử nghiệm đầu tiên thực sự vô dụng vì nó không giúp tìm ra lỗi. Bạn không biết liệu nó thất bại vì một số không hợp lệ hay vì cả hai bộ sưu tập đều khác nhau.


Tại sao? Vì vậy, tôi có thể lặp lại chỉ một lần ngay cả với các câu lệnh mong muốn bộ sưu tập được cụ thể hóa

Tôi tự hỏi tại sao bạn quan tâm đến nó? Đây là những bài kiểm tra đơn vị. Bạn không phải tối ưu hóa từng bit trong số chúng và thường các bài kiểm tra không yêu cầu hàng triệu mục nên hiệu suất không phải là vấn đề đáng lo ngại.

Bạn sẽ cần phải duy trì các bài kiểm tra như vậy, tại sao bạn nên làm cho chúng phức tạp hơn sau đó cần thiết? Viết những khẳng định đơn giản mà hiệu quả.


Nếu vì một lý do nào đó, một xác nhận cần phải được chôn trong luồng điều khiển, một cách để đảm bảo rằng nó đã được thực thi là giữ một bộ đếm / cờ được tăng / đặt thành đúng trước khi xác nhận lồng nhau. Sau đó, chúng tôi có thể khẳng định rằng luồng điều khiển dự kiến ​​đã được thực hiện bằng cách kiểm tra bộ đếm này. Không hoàn hảo, nhưng phần lớn giải quyết những lời chỉ trích đầu tiên của bạn.
amon

1
Ngoài ra, bạn hoặc ai đó sẽ quay lại xác nhận hoãn lại sau 6 tháng và phải lãng phí thời gian để tìm ra nó.
DavidTheWin

Có điều gì đó sai với ví dụ của bạn. Gọi ToListsẽ lặp lại vô số, phải không?
RubberDuck

1
@RubberDuck có, nó sẽ và nó cũng sẽ thất bại tuy nhiên không phải tại Assert.Failnhưng tại CollectionAssertvà bạn sẽ không thể nói khẳng định nào thực sự sai. Ý tôi là VS sẽ không tập trung vào Assert.Failnhưng cái khác ... bây giờ bạn có thể gỡ lỗi.
t3chb0t
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.