Điều gì tạo nên một bài kiểm tra đơn vị tốt? [đóng cửa]


97

Tôi chắc rằng hầu hết các bạn đang viết rất nhiều bài kiểm tra tự động và bạn cũng đã gặp phải một số cạm bẫy phổ biến khi kiểm thử đơn vị.

Câu hỏi của tôi là bạn có tuân theo bất kỳ quy tắc ứng xử nào cho các bài kiểm tra viết để tránh những rắc rối trong tương lai không? Cụ thể hơn: Các tính chất của bài kiểm tra đơn vị tốt là gì hoặc bạn viết bài kiểm tra của mình như thế nào?

Đề xuất ngôn ngữ bất khả tri được khuyến khích.

Câu trả lời:


93

Hãy để tôi bắt đầu bằng cách cắm các nguồn - Kiểm tra Đơn vị Thực dụng trong Java với JUnit (Có một phiên bản với C # -Nunit nữa .. nhưng tôi có cái này .. nó không khả thi cho hầu hết các phần. Được khuyến nghị.)

Bài kiểm tra tốt phải là MỘT CHUYẾN ĐI (Từ viết tắt không đủ dính - Tôi có một bản in của bảng gian lận trong cuốn sách mà tôi phải kéo ra để đảm bảo rằng tôi làm đúng ..)

  • Tự động : Việc gọi các bài kiểm tra cũng như kiểm tra kết quả cho PASS / FAIL phải tự động
  • Triệt : Che phủ; Mặc dù các lỗi có xu hướng tập hợp xung quanh các vùng nhất định trong mã, hãy đảm bảo rằng bạn kiểm tra tất cả các đường dẫn và tình huống chính. Sử dụng các công cụ nếu bạn phải biết các vùng chưa được kiểm tra
  • Lặp lại : Các thử nghiệm phải cho kết quả giống nhau mỗi lần .. mọi lúc. Các thử nghiệm không nên dựa vào các thông số không thể kiểm soát được.
  • Độc lập : Rất quan trọng.
    • Các bài kiểm tra chỉ nên kiểm tra một thứ tại một thời điểm. Nhiều xác nhận là được miễn là tất cả chúng đều đang thử nghiệm một tính năng / hành vi. Khi kiểm tra không thành công, nó sẽ xác định vị trí của vấn đề.
    • Các bài kiểm tra không nên dựa vào nhau - Cô lập. Không có giả định nào về thứ tự thực hiện kiểm tra. Đảm bảo 'phương tiện chặn sạch' trước mỗi lần kiểm tra bằng cách sử dụng thiết lập / chia nhỏ một cách thích hợp
  • Chuyên nghiệp : Về lâu dài, bạn sẽ có nhiều mã thử nghiệm như sản xuất (nếu không nhiều hơn), do đó hãy tuân theo cùng một tiêu chuẩn thiết kế tốt cho mã thử nghiệm của bạn. Các lớp phương thức được kiểm chứng tốt với các tên tiết lộ có chủ đích, Không trùng lặp, các bài kiểm tra có tên tốt, v.v.

  • Các bài kiểm tra tốt cũng chạy Nhanh . bất kỳ bài kiểm tra nào mất hơn nửa giây để chạy .. cần được thực hiện. Bộ thử nghiệm càng mất nhiều thời gian để chạy .. nó sẽ được chạy ít thường xuyên hơn. Càng có nhiều thay đổi, nhà phát triển sẽ cố gắng lén lút giữa các lần chạy .. nếu bất cứ điều gì bị hỏng .. sẽ mất nhiều thời gian hơn để tìm ra thay đổi nào là thủ phạm.

Cập nhật 2010-08:

  • Đọc được : Đây có thể được coi là một phần của Chuyên nghiệp - tuy nhiên nó không thể đủ căng thẳng. Thử nghiệm axit sẽ là để tìm một người không thuộc nhóm của bạn và yêu cầu họ tìm ra hành vi được kiểm tra trong vòng vài phút. Các bài kiểm tra cần được duy trì giống như mã sản xuất - vì vậy hãy làm cho nó dễ đọc ngay cả khi cần nhiều nỗ lực hơn. Các bài kiểm tra phải đối xứng (theo một mẫu) và ngắn gọn (kiểm tra một hành vi tại một thời điểm). Sử dụng quy ước đặt tên nhất quán (ví dụ: kiểu TestDox). Tránh làm lộn xộn bài kiểm tra với "chi tiết ngẫu nhiên" .. trở thành một người tối giản.

Ngoài những điều này, hầu hết các hướng dẫn khác là các nguyên tắc cắt giảm công việc mang lại lợi ích thấp: ví dụ: 'Không kiểm tra mã mà bạn không sở hữu' (ví dụ: DLL của bên thứ ba). Đừng đi thử nghiệm getters và setters. Theo dõi tỷ lệ chi phí trên lợi ích hoặc xác suất sai sót.


Chúng tôi có thể không đồng ý về việc sử dụng Mocks, nhưng đây là một bản viết rất hay về các phương pháp hay nhất của unit testing.
Justin Standard

Sau đó, tôi sẽ đưa ra câu trả lời này như một câu trả lời vì tôi thấy từ viết tắt "A TRIP" hữu ích.
Spoike

3
Tôi đồng ý với hầu hết các phần, nhưng muốn chỉ ra rằng có một lợi ích khi kiểm tra mã mà bạn không sở hữu ... Bạn đang kiểm tra xem nó có đáp ứng các yêu cầu của bạn không. Còn cách nào khác để bạn có thể tự tin rằng việc nâng cấp sẽ không phá vỡ hệ thống của bạn? (Nhưng tất nhiên, hãy ghi nhớ tỷ lệ chi phí / lợi ích khi làm như vậy.)
Vỡ mộng

@Craig - Tôi tin rằng bạn đang đề cập đến (cấp độ giao diện) các bài kiểm tra hồi quy (hoặc bài kiểm tra người học trong một số trường hợp), ghi lại hành vi mà bạn phụ thuộc vào. Tôi không viết các bài kiểm tra 'đơn vị' cho mã của bên thứ ba vì a. nhà cung cấp biết nhiều về mã đó hơn tôi b. Nhà cung cấp không bị ràng buộc phải duy trì bất kỳ triển khai cụ thể nào. Tôi không kiểm soát thay đổi đối với cơ sở mã đó và tôi không muốn dành thời gian sửa các bài kiểm tra bị hỏng bằng bản nâng cấp. Vì vậy, tôi thà mã lên một số xét nghiệm hồi quy cao cấp cho hành vi mà tôi sử dụng (và muốn được thông báo khi bị hỏng)
Gishu

@Gishu: Đúng vậy! Các bài kiểm tra chỉ phải được thực hiện ở cấp độ giao diện; và trên thực tế, hầu hết bạn nên thử nghiệm các tính năng mà bạn thực sự sử dụng. Hơn nữa, khi chọn những gì để viết các bài kiểm tra này; Tôi nhận thấy rằng các khuôn khổ kiểm tra 'đơn vị' đơn giản thường hoàn toàn phù hợp với hóa đơn.
Vỡ mộng

42
  1. Đừng viết những bài kiểm tra khổng lồ. Như 'đơn vị' trong 'thử nghiệm đơn vị' gợi ý, hãy làm cho mỗi đơn vị càng nguyên tử và càng cô lập càng tốt. Nếu bạn phải tạo điều kiện tiên quyết bằng cách sử dụng các đối tượng giả, thay vì tạo lại quá nhiều môi trường người dùng điển hình theo cách thủ công.
  2. Đừng thử nghiệm những thứ rõ ràng là hiệu quả. Tránh kiểm tra các lớp từ nhà cung cấp bên thứ ba, đặc biệt là nhà cung cấp cung cấp các API cốt lõi của khung mà bạn viết mã. Ví dụ: không kiểm tra thêm một mục vào lớp Hashtable của nhà cung cấp.
  3. Cân nhắc sử dụng một công cụ bao phủ mã như NCover để giúp khám phá các trường hợp cạnh mà bạn chưa kiểm tra.
  4. Viết thử trước khi thực hiện. Hãy coi thử nghiệm như một đặc điểm kỹ thuật mà việc triển khai của bạn sẽ tuân theo. Cf cũng là phát triển theo hướng hành vi, một nhánh cụ thể hơn của phát triển theo hướng thử nghiệm.
  5. Hãy kiên định. Nếu bạn chỉ viết các bài kiểm tra cho một số mã của mình, nó hầu như không hữu ích. Nếu bạn làm việc theo nhóm và một số hoặc tất cả những người khác không viết bài kiểm tra, thì nó cũng không hữu ích lắm. Thuyết phục bản thân và mọi người về tầm quan trọng (và đặc tính tiết kiệm thời gian ) của thử nghiệm, hoặc đừng bận tâm.

1
Câu trả lời tốt. Nhưng sẽ không tệ lắm nếu bạn không kiểm tra đơn vị cho mọi thứ trong một lần giao hàng. Chắc chắn là tốt hơn, nhưng cần phải có sự cân bằng và thực dụng. Re: đưa đồng nghiệp của bạn lên tàu; đôi khi bạn chỉ cần làm điều đó để chứng minh giá trị và như một điểm tham chiếu.
Martin Clarke

1
Tôi đồng ý. Tuy nhiên, về lâu dài, bạn cần phải có khả năng dựa vào các bài kiểm tra ở đó, tức là có thể cho rằng những cạm bẫy thông thường sẽ bị chúng bắt. Nếu không, lợi ích sẽ bị giảm đi hàng loạt.
Sören Kuklau 14/09/08

2
"Nếu bạn chỉ viết các bài kiểm tra cho một số mã của mình, nó hầu như không hữu ích." Đây đúng là tình trạng đó phải không? Tôi đã có các dự án với độ phủ mã 20% (các khu vực quan trọng / dễ gặp lỗi) và chúng đã giúp tôi rất nhiều, và các dự án cũng tốt.
dr. ác

1
Tôi đồng ý với Slough. Ngay cả khi chỉ có một vài bài kiểm tra, nhưng chúng được viết tốt và đủ cô lập, chúng sẽ giúp ích rất nhiều.
Spoike

41

Hầu hết các câu trả lời ở đây dường như đề cập đến các phương pháp hay nhất về kiểm thử đơn vị nói chung (khi nào, ở đâu, tại sao và cái gì), thay vì thực sự tự viết các bài kiểm tra (như thế nào). Vì câu hỏi có vẻ khá cụ thể về phần "làm thế nào", tôi nghĩ tôi sẽ đăng bài này, trích từ một bài thuyết trình về "chiếc túi nâu" mà tôi đã thực hiện tại công ty của mình.

5 quy luật của bài kiểm tra viết của Womp:


1. Sử dụng tên phương pháp kiểm tra mô tả, dài.

   - Map_DefaultConstructorShouldCreateEmptyGisMap()
   - ShouldAlwaysDelegateXMLCorrectlyToTheCustomHandlers()
   - Dog_Object_Should_Eat_Homework_Object_When_Hungry()

2. Viết các bài kiểm tra của bạn theo kiểu Sắp xếp / Hành động / Khẳng định .

  • Mặc dù chiến lược tổ chức này đã tồn tại được một thời gian và được gọi là nhiều thứ, nhưng việc giới thiệu từ viết tắt "AAA" gần đây là một cách tuyệt vời để thực hiện điều này. Làm cho tất cả các bài kiểm tra của bạn nhất quán với kiểu AAA giúp chúng dễ đọc và dễ bảo trì.

3. Luôn cung cấp thông báo lỗi với các Cảnh báo của bạn.

Assert.That(x == 2 && y == 2, "An incorrect number of begin/end element 
processing events was raised by the XElementSerializer");
  • Một thực hành đơn giản nhưng bổ ích giúp bạn thấy rõ điều gì đã thất bại trong ứng dụng chạy của bạn. Nếu bạn không cung cấp thông báo, bạn sẽ thường nhận được thông báo như "Dự kiến ​​đúng, là sai" trong kết quả lỗi của bạn, điều này khiến bạn phải thực sự đọc bài kiểm tra để tìm ra điều gì sai.

4. Nhận xét lý do thử nghiệm - giả định kinh doanh là gì?

  /// A layer cannot be constructed with a null gisLayer, as every function 
  /// in the Layer class assumes that a valid gisLayer is present.
  [Test]
  public void ShouldNotAllowConstructionWithANullGisLayer()
  {
  }
  • Điều này có vẻ hiển nhiên, nhưng cách làm này sẽ bảo vệ tính toàn vẹn của các bài kiểm tra của bạn khỏi những người không hiểu lý do đằng sau bài kiểm tra ngay từ đầu. Tôi đã thấy nhiều bài kiểm tra bị xóa hoặc sửa đổi hoàn toàn ổn, đơn giản là vì người đó không hiểu các giả định mà bài kiểm tra đang xác minh.
  • Nếu thử nghiệm nhỏ hoặc tên phương pháp đủ mô tả, có thể cho phép bỏ nhận xét.

5. Mọi thử nghiệm phải luôn hoàn nguyên trạng thái của bất kỳ tài nguyên nào mà nó chạm vào

  • Sử dụng chế độ giả nếu có thể để tránh giao dịch với tài nguyên thực.
  • Việc dọn dẹp phải được thực hiện ở cấp độ thử nghiệm. Kiểm tra không được phụ thuộc vào thứ tự thực hiện.

2
+1 vì điểm 1, 2 và 5 là quan trọng. 3 và 4 có vẻ khá thừa đối với các bài kiểm tra đơn vị, nếu bạn đã sử dụng tên phương pháp kiểm thử mô tả, nhưng tôi khuyên bạn nên lập tài liệu về các bài kiểm tra nếu chúng có phạm vi lớn (kiểm thử chức năng hoặc chấp nhận).
Spoike

+1 cho các kiến ​​thức và ví dụ thực tế và thực tế
Phil

17

Hãy ghi nhớ những mục tiêu này (phỏng theo cuốn sách Các mẫu thử nghiệm xUnit của Meszaros)

  • Các thử nghiệm nên giảm rủi ro, không giới thiệu nó.
  • Các bài kiểm tra phải dễ chạy.
  • Kiểm tra phải dễ dàng duy trì khi hệ thống phát triển xung quanh chúng

Một số điều để làm cho việc này dễ dàng hơn:

  • Thử nghiệm chỉ nên thất bại vì một lý do.
  • Các bài kiểm tra chỉ nên kiểm tra một thứ
  • Giảm thiểu phụ thuộc kiểm tra (không phụ thuộc vào cơ sở dữ liệu, tệp, ui, v.v.)

Đừng quên rằng bạn cũng có thể thực hiện kiểm tra tích hợp với khuôn khổ xUnit của mình nhưng hãy giữ các kiểm tra tích hợp và kiểm tra đơn vị riêng biệt


Tôi đoán ý bạn là bạn đã chuyển thể từ cuốn sách "Các mẫu thử nghiệm xUnit" của Gerard Meszaros. xunitpatterns.com
Spoike 14/09/08

Đúng vậy, bạn nói đúng. Tôi sẽ làm rõ điều đó trong bài đăng
Mendelt 14/09/08

Điểm xuất sắc. Kiểm tra đơn vị có thể rất hữu ích nhưng điều rất quan trọng là tránh rơi vào bẫy của việc kiểm tra đơn vị phức tạp, phụ thuộc lẫn nhau tạo ra một khoản thuế lớn cho bất kỳ nỗ lực thay đổi hệ thống nào.
Wedge

9

Các thử nghiệm nên được cách ly. Một bài kiểm tra không nên phụ thuộc vào bài kiểm tra khác. Hơn nữa, một bài kiểm tra không nên dựa vào các hệ thống bên ngoài. Nói cách khác, hãy kiểm tra mã của bạn , không phải mã mà mã của bạn phụ thuộc vào. Bạn có thể kiểm tra những tương tác đó như một phần của quá trình tích hợp hoặc kiểm tra chức năng.


9

Một số thuộc tính của các bài kiểm tra đơn vị lớn:

  • Khi một bài kiểm tra không thành công, cần phải thấy ngay vấn đề nằm ở đâu. Nếu bạn phải sử dụng trình gỡ lỗi để theo dõi vấn đề, thì các thử nghiệm của bạn không đủ chi tiết. Có chính xác một khẳng định cho mỗi bài kiểm tra sẽ giúp ích ở đây.

  • Khi bạn cấu trúc lại, không có thử nghiệm nào bị lỗi.

  • Các bài kiểm tra sẽ chạy nhanh đến mức bạn không bao giờ ngần ngại khi chạy chúng.

  • Tất cả các bài kiểm tra phải luôn vượt qua; không có kết quả không xác định.

  • Các bài kiểm tra đơn vị phải được kiểm tra kỹ lưỡng, giống như mã sản xuất của bạn.

@Alotor: Nếu bạn đang gợi ý rằng một thư viện chỉ nên có các bài kiểm tra đơn vị tại API bên ngoài của nó, tôi không đồng ý. Tôi muốn các bài kiểm tra đơn vị cho từng lớp, bao gồm các lớp mà tôi không tiếp xúc với người gọi bên ngoài. (Tuy nhiên, nếu tôi cảm thấy cần phải viết các bài kiểm tra cho các phương thức riêng tư, thì tôi cần phải cấu trúc lại. )


CHỈNH SỬA: Có một nhận xét về sự trùng lặp do "một khẳng định cho mỗi thử nghiệm". Cụ thể, nếu bạn có một số mã để thiết lập một kịch bản và sau đó muốn thực hiện nhiều xác nhận về nó, nhưng chỉ có một xác nhận cho mỗi thử nghiệm, bạn có thể sao chép thiết lập qua nhiều thử nghiệm.

Tôi không áp dụng cách tiếp cận đó. Thay vào đó, tôi sử dụng đồ đạc thử nghiệm cho mỗi tình huống . Đây là một ví dụ sơ bộ:

[TestFixture]
public class StackTests
{
    [TestFixture]
    public class EmptyTests
    {
        Stack<int> _stack;

        [TestSetup]
        public void TestSetup()
        {
            _stack = new Stack<int>();
        }

        [TestMethod]
        [ExpectedException (typeof(Exception))]
        public void PopFails()
        {
            _stack.Pop();
        }

        [TestMethod]
        public void IsEmpty()
        {
            Assert(_stack.IsEmpty());
        }
    }

    [TestFixture]
    public class PushedOneTests
    {
        Stack<int> _stack;

        [TestSetup]
        public void TestSetup()
        {
            _stack = new Stack<int>();
            _stack.Push(7);
        }

        // Tests for one item on the stack...
    }
}

Tôi không đồng ý về chỉ một khẳng định cho mỗi bài kiểm tra. Bạn càng có nhiều xác nhận trong thử nghiệm thì bạn càng có ít trường hợp thử nghiệm cắt và dán hơn. Tôi tin rằng một trường hợp thử nghiệm nên tập trung vào một kịch bản hoặc đường dẫn mã và các xác nhận phải xuất phát từ tất cả các giả định và yêu cầu để hoàn thành kịch bản đó.
Lucas B

Tôi nghĩ rằng chúng tôi đồng ý rằng DRY áp dụng cho các bài kiểm tra đơn vị. Như tôi đã nói, "Các bài kiểm tra đơn vị nên được kiểm tra kỹ lưỡng". Tuy nhiên, có nhiều cách để giải quyết sự trùng lặp. Một, như bạn đã đề cập, là có một bài kiểm tra đơn vị trước tiên gọi mã đang được kiểm tra, và sau đó xác nhận nhiều lần. Một giải pháp thay thế là tạo một "bộ cố định thử nghiệm" mới cho kịch bản, mã này gọi mã đang được thử nghiệm trong bước Khởi tạo / Thiết lập và sau đó có một loạt các bài kiểm tra đơn vị chỉ cần xác nhận.
Jay Bazuzi

Quy tắc chung của tôi là, nếu bạn đang sử dụng copy-paste, bạn đang làm sai. Một trong những câu nói yêu thích của tôi là "Copy-paste không phải là một mẫu thiết kế." Tôi cũng đồng ý một khẳng định cho mỗi bài kiểm tra đơn vị nói chung là một ý kiến ​​hay, nhưng không phải lúc nào tôi cũng nhấn mạnh vào điều đó. Tôi thích kiểu "kiểm tra một thứ trên mỗi đơn vị bài kiểm tra" tổng quát hơn. Mặc dù điều đó thường chuyển thành một xác nhận cho mỗi đơn vị thử nghiệm.
Jon Turner

7

Những gì bạn đang theo đuổi là mô tả các hành vi của lớp được kiểm tra.

  1. Xác minh các hành vi mong đợi.
  2. Xác minh các trường hợp lỗi.
  3. Phạm vi của tất cả các đường dẫn mã trong lớp.
  4. Thực hiện tất cả các chức năng thành viên trong lớp.

Mục đích cơ bản là tăng cường sự tự tin của bạn trong hành vi của lớp.

Điều này đặc biệt hữu ích khi xem xét cấu trúc lại mã của bạn. Martin Fowler có một bài viết thú vị về việc thử nghiệm trên trang web của anh ấy.

HTH.

cổ vũ,

Rob


Rob - điều này là tốt, nhưng nó không đúng mục đích. Tại sao bạn làm tất cả những điều này? Suy nghĩ theo cách này có thể giúp những người khác đi xuống con đường TDD.
Mark Levison

7

Kiểm tra ban đầu sẽ thất bại. Sau đó, bạn nên viết mã khiến chúng vượt qua, nếu không, bạn có nguy cơ viết một bài kiểm tra bị nghe trộm và luôn vượt qua.


@Rismo Không độc quyền. Theo định nghĩa những gì Quarrelsome viết ở đây là dành riêng cho phương pháp "Thử nghiệm đầu tiên", một phần của TDD. TDD cũng tính đến việc tái cấu trúc. Định nghĩa "quần thông minh" nhất mà tôi đã đọc là TDD = Test First + Refactor.
Spoike 14/09/08

Vâng, nó không cần phải là TDD, chỉ cần đảm bảo rằng bài kiểm tra của bạn không thành công trước tiên. Sau đó đấu dây vào phần còn lại sau đó. Điều này thường xảy ra nhất khi thực hiện TDD nhưng bạn cũng có thể áp dụng nó khi không sử dụng TDD.
Quibblesome 15/09/08

6

Tôi thích từ viết tắt Right BICEP từ cuốn sách Kiểm tra Đơn vị Thực dụng đã nói ở trên :

  • Đúng : Kết quả có đúng không?
  • B : Tất cả các điều kiện dư thừa b có đúng không?
  • I : Chúng ta có thể kiểm tra các mối quan hệ nghịch đảo của tôi không?
  • C : Có thể chúng tôi c kết quả ross kiểm tra sử dụng các phương tiện khác?
  • E : Chúng ta có thể buộc e điều kiện rror xảy ra?
  • P : Các đặc điểm sai lệch p có nằm trong giới hạn không?

Cá nhân tôi cảm thấy rằng bạn có thể tiến khá xa bằng cách kiểm tra xem bạn có nhận được kết quả phù hợp hay không (1 + 1 sẽ trả về 2 trong một hàm cộng), thử tất cả các điều kiện biên mà bạn có thể nghĩ đến (chẳng hạn như sử dụng hai số trong đó tổng lớn hơn giá trị tối đa số nguyên trong hàm thêm) và buộc các điều kiện lỗi như lỗi mạng.


6

Các bài kiểm tra tốt cần phải được duy trì.

Tôi chưa tìm ra cách thực hiện điều này cho các môi trường phức tạp.

Tất cả các sách giáo khoa bắt đầu không được dán khi cơ sở mã của bạn bắt đầu đạt đến hàng trăm 1000 hoặc hàng triệu dòng mã.

  • Tương tác nhóm bùng nổ
  • số lượng trường hợp thử nghiệm bùng nổ
  • sự tương tác giữa các thành phần bùng nổ.
  • thời gian để xây dựng tất cả các kỳ lân trở thành một phần quan trọng trong thời gian xây dựng
  • một thay đổi API có thể xuất hiện hàng trăm trường hợp thử nghiệm. Mặc dù việc thay đổi mã sản xuất rất dễ dàng.
  • số lượng sự kiện cần thiết để trình tự các quy trình ở trạng thái phù hợp tăng lên, do đó làm tăng thời gian thực hiện kiểm tra.

Kiến trúc tốt có thể kiểm soát một số sự bùng nổ tương tác, nhưng chắc chắn khi các hệ thống trở nên phức tạp hơn, hệ thống kiểm tra tự động sẽ phát triển cùng với nó.

Đây là nơi bạn bắt đầu phải đối mặt với sự đánh đổi:

  • chỉ kiểm tra API bên ngoài, nếu không, việc cấu trúc lại nội bộ dẫn đến việc làm lại trường hợp thử nghiệm đáng kể.
  • việc thiết lập và chia nhỏ của mỗi bài kiểm tra trở nên phức tạp hơn do một hệ thống con được đóng gói giữ lại nhiều trạng thái hơn.
  • biên dịch hàng đêm và thực hiện kiểm tra tự động tăng lên hàng giờ.
  • thời gian biên dịch và thực thi tăng lên có nghĩa là các nhà thiết kế không hoặc sẽ không chạy tất cả các thử nghiệm
  • để giảm thời gian thực hiện kiểm tra, bạn cân nhắc các kiểm tra trình tự để thực hiện giảm thiết lập và gỡ bỏ

Bạn cũng cần quyết định:

bạn lưu trữ các trường hợp thử nghiệm ở đâu trong cơ sở mã của bạn?

  • làm thế nào để bạn ghi lại các trường hợp thử nghiệm của bạn?
  • có thể sử dụng lại đồ đạc thử nghiệm để tiết kiệm bảo trì trường hợp thử nghiệm không?
  • điều gì xảy ra khi việc thực thi trường hợp thử nghiệm hàng đêm không thành công? Ai thực hiện bộ ba?
  • Làm thế nào để bạn duy trì các đối tượng giả? Nếu bạn có 20 mô-đun, tất cả đều sử dụng hương vị riêng của một API ghi nhật ký giả, thì việc thay đổi API sẽ xảy ra nhanh chóng. Không chỉ các trường hợp thử nghiệm thay đổi mà cả 20 đối tượng thử nghiệm cũng thay đổi. 20 mô-đun đó được viết trong nhiều năm bởi nhiều nhóm khác nhau. Đó là một vấn đề tái sử dụng cổ điển.
  • các cá nhân và nhóm của họ hiểu giá trị của các bài kiểm tra tự động mà họ không thích cách nhóm khác thực hiện. :-)

Tôi có thể đi mãi mãi, nhưng quan điểm của tôi là:

Các thử nghiệm cần phải được duy trì.


5

Tôi đã đề cập đến những nguyên tắc này một thời gian trong bài viết Tạp chí MSDN này mà tôi nghĩ là quan trọng đối với bất kỳ nhà phát triển nào nên đọc.

Cách tôi xác định các bài kiểm tra đơn vị "tốt" là nếu chúng có ba thuộc tính sau:

  • Chúng có thể đọc được (đặt tên, xác nhận, biến, độ dài, độ phức tạp ..)
  • Chúng có thể bảo trì (không logic, không quá chỉ định, dựa trên trạng thái, cấu trúc lại ..)
  • Chúng đáng tin cậy (kiểm tra điều đúng, kiểm tra cô lập, không tích hợp ..)

Roy, tôi hết lòng đồng ý. Những thứ này quan trọng hơn rất nhiều so với độ che phủ của ốp lưng.
Matt Hinze

đáng tin cậy - điểm xuất sắc!
ratkok

4
  • Kiểm thử Đơn vị chỉ kiểm tra API bên ngoài của Đơn vị của bạn, bạn không nên kiểm tra hành vi bên trong.
  • Mỗi bài kiểm tra của TestCase nên kiểm tra một (và chỉ một) phương pháp bên trong API này.
    • Các trường hợp thử nghiệm bổ sung nên được bao gồm cho các trường hợp thất bại.
  • Kiểm tra mức độ phù hợp của các bài kiểm tra của bạn: Khi một đơn vị được kiểm tra, 100% các dòng bên trong đơn vị này phải được thực thi.

2

Jay Fields có rất nhiều lời khuyên tốt về cách viết các bài kiểm tra đơn vị và có một bài đăng mà anh ấy tóm tắt những lời khuyên quan trọng nhất . Ở đó, bạn sẽ đọc rằng bạn nên suy nghĩ chín chắn về bối cảnh của mình và đánh giá xem lời khuyên có đáng với bạn không. Bạn nhận được rất nhiều câu trả lời tuyệt vời ở đây, nhưng tùy thuộc vào bạn quyết định câu trả lời nào phù hợp nhất với ngữ cảnh của bạn. Hãy thử chúng và chỉ cần cấu trúc lại nếu nó có mùi khó chịu với bạn.

Trân trọng


1

Đừng bao giờ cho rằng phương thức 2 dòng tầm thường sẽ hoạt động. Viết một bài kiểm tra đơn vị nhanh là cách duy nhất để ngăn chặn bài kiểm tra rỗng bị thiếu, dấu trừ đặt sai vị trí và / hoặc lỗi xác định phạm vi tinh vi khiến bạn không thể tránh khỏi, khi bạn thậm chí còn ít thời gian để giải quyết nó hơn bây giờ.


1

Tôi thứ hai câu trả lời "MỘT CHUYẾN ĐI", ngoại trừ các bài kiểm tra NÊN dựa vào nhau !!!

Tại sao?

KHÔ - Không lặp lại chính mình - cũng áp dụng cho thử nghiệm! Kiểm tra phụ thuộc có thể giúp 1) tiết kiệm thời gian thiết lập, 2) tiết kiệm tài nguyên cố định và 3) xác định lỗi. Tất nhiên, chỉ khi khung thử nghiệm của bạn hỗ trợ các phụ thuộc hạng nhất. Nếu không, tôi thừa nhận, họ rất tệ.

Theo dõi http://www.iam.unibe.ch/~scg/Research/JExample/


Tôi đồng ý với bạn. TestNG là một khuôn khổ khác trong đó các phụ thuộc được phép dễ dàng.
Davide

0

Thông thường các bài kiểm tra đơn vị dựa trên đối tượng giả hoặc dữ liệu giả. Tôi muốn viết ba loại bài kiểm tra đơn vị:

  • Các bài kiểm tra đơn vị "tạm thời": chúng tạo các đối tượng / dữ liệu giả của riêng mình và kiểm tra chức năng của chúng với nó, nhưng phá hủy mọi thứ và không để lại dấu vết (giống như không có dữ liệu trong cơ sở dữ liệu thử nghiệm)
  • kiểm tra đơn vị "liên tục": chúng kiểm tra các chức năng trong mã của bạn tạo ra các đối tượng / dữ liệu mà sau này sẽ cần đến bởi chức năng nâng cao hơn để kiểm tra đơn vị của riêng chúng (tránh để các chức năng nâng cao đó tạo lại mỗi khi tập hợp các đối tượng / dữ liệu giả của riêng chúng)
  • kiểm thử đơn vị "dựa trên liên tục": kiểm thử đơn vị sử dụng các đối tượng / dữ liệu giả đã có sẵn (vì được tạo trong một phiên kiểm thử đơn vị khác) bởi kiểm thử đơn vị liên tục.

Vấn đề là tránh phát lại mọi thứ để có thể kiểm tra mọi chức năng.

  • Tôi chạy loại thứ ba rất thường xuyên vì tất cả các đối tượng / dữ liệu giả đều đã ở đó.
  • Tôi chạy loại thứ hai bất cứ khi nào mô hình của tôi thay đổi.
  • Tôi chạy cái đầu tiên để kiểm tra các chức năng rất cơ bản một lần, để kiểm tra các hồi quy cơ bản.

0

Hãy suy nghĩ về 2 loại kiểm tra và xử lý chúng khác nhau - kiểm tra chức năng và kiểm tra hiệu suất.

Sử dụng các đầu vào và số liệu khác nhau cho từng loại. Bạn có thể cần sử dụng các phần mềm khác nhau cho từng loại kiểm tra.


Sau đó, những gì về kiểm thử đơn vị?
Spoike

0

Tôi sử dụng quy ước đặt tên thử nghiệm nhất quán được mô tả bởi tiêu chuẩn Đặt tên đơn vị thử nghiệm của Roy Osherove Mỗi phương thức trong một lớp trường hợp thử nghiệm nhất định có kiểu đặt tên như sau MethodUnderTest_Scenario_EosystemResult.

    Phần tên thử nghiệm đầu tiên là tên của phương pháp trong hệ thống đang thử nghiệm.
    Tiếp theo là kịch bản cụ thể đang được thử nghiệm.
    Cuối cùng là kết quả của kịch bản đó.

Mỗi phần sử dụng Upper Camel Case và được phân định bằng điểm dưới.

Tôi đã thấy điều này hữu ích khi tôi chạy thử nghiệm, thử nghiệm được nhóm theo tên của phương pháp đang thử nghiệm. Và có một quy ước cho phép các nhà phát triển khác hiểu ý định thử nghiệm.

Tôi cũng nối các tham số vào tên Phương thức nếu phương thức đang kiểm tra đã bị quá 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.