Kiểm tra đơn vị - bắt đầu


14

Tôi chỉ mới bắt đầu với thử nghiệm đơn vị nhưng tôi không chắc liệu tôi có thực sự hiểu quan điểm của tất cả không. Tôi đọc hướng dẫn và sách về tất cả, nhưng tôi chỉ có hai câu hỏi nhanh:

  1. Tôi nghĩ mục đích của kiểm thử đơn vị là để kiểm tra mã chúng tôi thực sự đã viết. Tuy nhiên, đối với tôi, dường như để có thể chạy thử nghiệm, chúng tôi phải thay đổi mã gốc, tại thời điểm đó chúng tôi không thực sự kiểm tra mã chúng tôi đã viết mà là mã chúng tôi đã viết để kiểm tra.

  2. Hầu hết các mã của chúng tôi dựa vào các nguồn bên ngoài. Tuy nhiên, khi cấu trúc lại mã của chúng tôi, thậm chí nó sẽ phá vỡ mã gốc, các thử nghiệm của chúng tôi vẫn chạy tốt, vì các nguồn bên ngoài chỉ là muck-up bên trong các trường hợp thử nghiệm của chúng tôi. Nó không đánh bại mục đích thử nghiệm đơn vị?

Xin lỗi nếu tôi nghe có vẻ ngu ngốc ở đây, nhưng tôi nghĩ ai đó có thể khai sáng cho tôi một chút.

Cảm ơn trước.

Câu trả lời:


7

0,02 đô la của tôi ... đây là một chút chủ quan, vì vậy hãy mang theo một hạt muối, nhưng hy vọng nó sẽ khiến bạn suy nghĩ và / hoặc châm ngòi cho một số hộp thoại:

  1. Mục đích chính của kiểm thử đơn vị đối với tôi là để đảm bảo rằng mã mà bạn đã viết hoàn thành các hợp đồng và các trường hợp cạnh mà mã của bạn dự định thực hiện. Với các thử nghiệm đơn vị tại chỗ, bạn có thể đảm bảo tốt hơn rằng khi bạn (hoặc ai đó trong tương lai) tái cấu trúc mã của mình, mọi người tiêu dùng bên ngoài mã của bạn sẽ không bị ảnh hưởng nếu bạn có bảo hiểm nhà nước phù hợp. (ít nhất là đến mức độ mà bạn dự định sẽ không bị ảnh hưởng).

    Trong phần lớn các trường hợp, bạn sẽ có thể viết mã vừa có thể được chuyển đến sản xuất và có thể dễ dàng kiểm tra đơn vị. Một nơi tốt để bắt đầu có thể là xem xét các mô hình và khuôn khổ Dependency Injection. (Hoặc các triết lý khác cho ngôn ngữ / nền tảng của sự lựa chọn của bạn).

  2. Đúng là việc triển khai bên ngoài có thể ảnh hưởng đến mã của bạn. Tuy nhiên, đảm bảo rằng mã của bạn hoạt động chính xác như là một phần của hệ thống lớn hơn là một chức năng của kiểm tra tích hợp . (Điều này cũng có thể được tự động hóa với các mức độ nỗ lực khác nhau).

    Lý tưởng nhất là mã của bạn chỉ nên dựa vào các hợp đồng API của bất kỳ thành phần bên thứ 3 nào, điều đó có nghĩa là miễn là các giả của bạn hoàn thành API chính xác, các bài kiểm tra đơn vị của bạn vẫn cung cấp giá trị.

    Điều đó nói rằng tôi sẽ dễ dàng thừa nhận rằng đã có những lúc tôi từ bỏ thử nghiệm đơn vị để ủng hộ thử nghiệm tích hợp, nhưng đó chỉ là trường hợp mã của tôi phải tương tác rất nhiều với các thành phần bên thứ 3 với các API được ghi chép kém. (tức là ngoại lệ chứ không phải quy tắc).


5
  1. Hãy thử viết bài kiểm tra của bạn trước. Bằng cách đó, bạn sẽ có cơ sở vững chắc cho hành vi của mã của mình và thử nghiệm của bạn trở thành hợp đồng cho hành vi bắt buộc của mã của bạn. Do đó, việc thay đổi mã để vượt qua thử nghiệm trở thành "thay đổi mã để thực hiện hợp đồng do thử nghiệm đề xuất" thay vì "thay đổi mã để vượt qua thử nghiệm".
  2. Vâng, hãy cẩn thận về sự khác biệt giữa sơ khai và giả. Không bị ảnh hưởng bởi bất kỳ thay đổi nào trong mã là hành vi đặc trưng của sơ khai, nhưng không phải là giả. Hãy bắt đầu với định nghĩa của giả:

    Một đối tượng Mock thay thế một đối tượng thực trong các điều kiện thử nghiệm và cho phép xác minh các cuộc gọi (tương tác) với chính nó như là một phần của thử nghiệm hệ thống hoặc đơn vị.

    -Các nghệ thuật kiểm tra đơn vị

Về cơ bản, các giả của bạn nên kiểm tra hành vi cần thiết của các tương tác của bạn. Do đó, nếu tương tác của bạn với cơ sở dữ liệu không thành công sau khi tái cấu trúc, thử nghiệm của bạn bằng cách sử dụng giả cũng sẽ thất bại. Điều này tất nhiên có những hạn chế, nhưng với việc lập kế hoạch cẩn thận, các giả của bạn sẽ làm được nhiều hơn là chỉ "ngồi đó" và nó sẽ không "đánh bại mục đích thử nghiệm đơn vị".


1

Đặt một câu hỏi hay không phải là ngu ngốc.

Tôi sẽ giải quyết câu hỏi của bạn.

  1. Mục đích của kiểm thử đơn vị không phải là kiểm tra mã bạn đã viết . Nó không có khái niệm về thời gian. Chỉ trong TDD, bạn phải thử nghiệm trước, nhưng điều đó không áp dụng đúng cho bất kỳ loại thử nghiệm đơn vị nào. Vấn đề là có thể tự động và kiểm tra hiệu quả chương trình của bạn ở cấp độ lớp. Bạn làm những gì bạn cần làm để đạt được điều đó, ngay cả khi điều đó có nghĩa là thay đổi mã. Và để tôi nói cho bạn một bí mật - nó thường có nghĩa như vậy.
  2. Khi bạn viết bài kiểm tra, bạn có 2 tùy chọn chính để giúp đảm bảo bài kiểm tra của bạn là chính xác:

    • Thay đổi các đầu vào cho mỗi thử nghiệm
    • Viết trường hợp kiểm thử để đảm bảo rằng chương trình của bạn hoạt động chính xác, sau đó viết trường hợp kiểm thử tương ứng để đảm bảo chương trình của bạn không hoạt động theo cách không nên

    Đây là một ví dụ:

    TEST(MyTest, TwoPlusTwoIsFour) {
        ASSERT_EQ(4, 2+2);
    }
    
    TEST(MyTest, TwoPlusThreeIsntFour) {
        ASSERT_NE(4, 2+3);
    }
    

    Trên hết, nếu bạn đang kiểm tra đơn vị logic bên trong mã của mình (không phải thư viện của bên thứ 3), thì bạn hoàn toàn không lo lắng về việc phá mã khác, trong bối cảnh đó. Về cơ bản, bạn đang kiểm tra cách logic của bạn kết thúc và sử dụng các tiện ích của bên thứ 3, đây là một kịch bản thử nghiệm cổ điển.

Khi bạn đã hoàn thành kiểm tra ở cấp lớp, bạn có thể tiếp tục kiểm tra sự tích hợp giữa các lớp của bạn (người hòa giải, từ những gì tôi hiểu) và thư viện của bên thứ 3. Các thử nghiệm này được gọi là các thử nghiệm tích hợp và không sử dụng các giả, mà là các triển khai cụ thể của tất cả các lớp. Chúng chậm hơn một chút, nhưng vẫn rất quan trọng!


1

Có vẻ như bạn có một ứng dụng nguyên khối thực hiện mọi thứ trong đó void main(), từ truy cập cơ sở dữ liệu đến việc tạo đầu ra. Có một số bước ở đây trước khi bạn có thể bắt đầu thử nghiệm đơn vị thích hợp.

1) Tìm một đoạn mã được viết / sao chép nhiều lần. Ngay cả khi nó chỉ string fullName = firstName + " " + lastName. Chia nó thành một phương thức, như:

private static string GetFullName (firstName, lastName)
{
    return firstName + " " + lastName;
}

Bây giờ bạn có một đoạn mã có thể kiểm tra đơn vị, tuy nhiên nó có thể là tầm thường. Viết một bài kiểm tra đơn vị cho nó. Rửa sạch và lặp lại quá trình này. Cuối cùng, bạn sẽ kết thúc với vô số các phương thức được nhóm hợp lý và bạn có thể trích xuất một số lớp từ nó. Hầu hết các lớp này sẽ được kiểm tra.

Như một phần thưởng, một khi bạn đã trích xuất nhiều lớp, bạn có thể trích xuất các giao diện từ chúng và cập nhật chương trình của bạn để nói chuyện với các giao diện thay vì chính các đối tượng. Tại thời điểm đó, bạn có thể sử dụng khung mô phỏng / gốc (hoặc thậm chí là hàng giả bằng tay của chính bạn) mà không cần thay đổi chương trình. Điều này rất hữu ích khi bạn trích xuất các truy vấn cơ sở dữ liệu vào một lớp (hoặc nhiều) vì bây giờ bạn có thể giả mạo dữ liệu mà truy vấn sẽ trả về.


0

Một số người thông minh nói "Nếu nó khó kiểm tra, có lẽ là mã xấu". Đó là lý do tại sao nó không phải là một điều xấu để viết lại mã, để có thể hủy bỏ nó. Mã với các phụ thuộc bên ngoài là RẤT CỨNG để kiểm tra, nó đại diện cho một mã risc cho mã, và nên tránh bất cứ khi nào có thể, và tập trung vào các khu vực cụ thể tích hợp của mã của bạn, fx. các loại mặt tiền / cổng loại. Điều này sẽ làm cho một sự thay đổi trong thành phần bên ngoài dễ dàng hơn để đối phó vớ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.