Tôi có nên kiểm tra đơn vị cho các khuyết tật đã biết?


37

Nếu mã của tôi chứa một lỗi đã biết cần được sửa, nhưng chưa được sửa và sẽ không được sửa cho bản phát hành hiện tại và có thể không được sửa trong tương lai có thể thấy được, nên có một thử nghiệm đơn vị thất bại cho lỗi đó trong bộ kiểm tra? Nếu tôi thêm bài kiểm tra đơn vị, nó sẽ (rõ ràng) thất bại, và làm quen với việc kiểm tra thất bại có vẻ như là một ý tưởng tồi. Mặt khác, nếu đó là một khiếm khuyết đã biết và có một trường hợp thất bại đã biết, thì có vẻ kỳ lạ khi giữ nó ra khỏi bộ thử nghiệm, vì tại một thời điểm nào đó nó sẽ được sửa chữa và thử nghiệm đã có sẵn.


6
Tôi không nghĩ vậy, tôi đặc biệt hỏi về bài kiểm tra đơn vị
Martijn

3
kiểm tra các lỗi đã biết được gọi là kiểm tra hồi quy , những kiểm tra này không liên quan gì đến kiểm tra đơn vị ... chính xác, sau này phụ thuộc vào ý kiến ​​của nhà phát triển - câu hỏi của bạn có thể không phải là trùng lặp, mà là một cuộc thăm dò ý kiến. Điều đặc biệt nổi bật là câu trả lời bạn chấp nhận hoàn toàn không sử dụng thuật ngữ "kiểm tra đơn vị", mà thay vào đó, khá hợp lý gọi những "thử nghiệm thất bại đã biết" này một cách hợp lý
gnat

3
Cảm ơn Michael, điều đó giúp ích về cách đánh dấu các bài kiểm tra như vậy trong JUnit, nhưng không thực sự về thực hành kiểm tra. gnat, tôi vẫn không hiểu làm thế nào bạn thấy một bài kiểm tra đơn vị thất bại là một bài kiểm tra hồi quy. Tôi cũng nhận được một sự rung cảm thụ động / hung hăng đặc biệt từ ý kiến ​​của bạn. Nếu bạn nghĩ tôi nên đặt câu hỏi khác nhau, xin vui lòng nói như vậy, vì tôi không thể giải quyết mối quan tâm của bạn nếu bạn diễn đạt chúng như thế này.
Martijn

3
@gnat: thành thật mà nói, IMHO không thành vấn đề nếu chúng tôi gọi các bài kiểm tra ở đây là bài kiểm tra "đơn vị" hoặc "hồi quy" - câu hỏi bạn liên kết cũng có trọng tâm khác và câu trả lời không áp dụng ở đây.
Doc Brown

Câu trả lời:


51

Câu trả lời là có, bạn nên viết chúng và bạn nên chạy chúng.

Khung kiểm tra của bạn cần một danh mục "các thử nghiệm thất bại đã biết" và bạn nên đánh dấu các thử nghiệm này là thuộc danh mục đó. Làm thế nào bạn làm điều đó phụ thuộc vào khuôn khổ.

Thật kỳ lạ, một bài kiểm tra thất bại đột nhiên vượt qua có thể thú vị như một bài kiểm tra vượt qua mà bất ngờ thất bại.


7
Một ví dụ về tính năng trên trong khung công tác nhỏ nhất của Python: docs.python.org/3.3/l Library / Wiêu
Jace Browning

5

Tôi nghĩ bạn nên có một bài kiểm tra đơn vị với hành vi hiện tại và trong các bình luận, thêm bài kiểm tra đúng và hành vi đúng. Thí dụ:

@Test
public void test() {
  // this is wrong, it should be fixed some time
  Assert.assertEquals(2, new Calculator().plus(2,2));
  // this is the expected behaviour, replace the above test when the fix is available
  // Assert.assertEquals(4, new Calculator().plus(2, 2));
}

Bằng cách này, khi có bản sửa lỗi, bản dựng sẽ thất bại, thông báo cho bạn bài kiểm tra thất bại. Khi bạn nhìn vào bài kiểm tra, bạn sẽ biết rằng bạn đã thay đổi hành vi và bài kiểm tra phải được cập nhật.

EDIT: Như Captain Man đã nói, trong các dự án lớn, điều này sẽ không được khắc phục sớm nhưng vì lợi ích tài liệu, câu trả lời ban đầu tốt hơn là không có gì.

Một cách tốt hơn để làm điều đó là sao chép thử nghiệm hiện tại, làm cho bản sao khẳng định đúng và @Ignorebằng một thông điệp, ví dụ

@Test
public void test() {
  Assert.assertEquals(2, new Calculator().plus(2,2));
}

@Ignore("fix me, Calculator is giving the wrong result, see ticket BUG-12345 and delete #test() when fixed")
@Test
public void fixMe() {
  Assert.assertEquals(4, new Calculator().plus(2, 2));
}

Điều này đi kèm với quy ước trong nhóm của bạn để giảm số lượng @Ignorebài kiểm tra d. Giống như cách bạn thực hiện với việc giới thiệu hoặc thay đổi thử nghiệm để phản ánh lỗi, ngoại trừ bạn không thất bại trong quá trình xây dựng nếu điều này rất quan trọng đối với nhóm của bạn, như OP nói rằng lỗi này sẽ không được đưa vào bản phát hành hiện tại .


1
Đây là lời khuyên tồi. Không ai sẽ cố gắng sửa nó. Mọi người sẽ chỉ mở các bài kiểm tra đơn vị cũ nếu có vấn đề biên dịch hoặc lỗi kiểm tra.
Thuyền trưởng Man

@CaptainMan Tôi đồng ý, tôi đã cập nhật câu trả lời của mình để cung cấp cách tốt hơn cho nhóm phát triển nhận thức được lỗi mà không bị lỗi khi xây dựng. Downvote của bạn đã được chứng minh cho câu trả lời ban đầu tôi đã đăng 3 năm trước, tôi tin rằng câu trả lời hiện tại là phù hợp hơn. Bạn sẽ làm điều đó theo cách khác?
Silviu Burcea

Đây là gần như chính xác những gì tôi làm trong những dịp hiếm hoi tôi không thể sửa lỗi bây giờ vì một số lý do. Tôi rất muốn nghe cách bạn xử lý tình huống @CaptainMan
RubberDuck

@RubberDuck Thực sự không có bất kỳ tình huống lý tưởng nào ở đây (ngoài việc sửa lỗi bây giờ haha). Đối với tôi, ít nhất là nhìn thấy trong kết quả thử nghiệm "10 đã qua, 0 thất bại, 1 bị bỏ qua" ít nhất là một số dấu hiệu cho thấy một điều gì đó đáng nghi với những người không quen thuộc với nó. Tôi thích @Ignorecách tiếp cận. Lý do chỉ sử dụng một nhận xét dường như không phải là một ý tưởng tốt đối với tôi là vì tôi không nghĩ mọi người sẽ thường mở các bài kiểm tra đơn vị để kiểm tra chúng (trừ khi chúng thất bại, hoặc (hy vọng) khi họ tự hỏi tại sao một cái gì đó bị bỏ qua ).
Thuyền trưởng Man

@RubberDuck Thực sự không có bất kỳ tình huống lý tưởng nào ở đây (ngoài việc sửa lỗi bây giờ haha). Đối với tôi, ít nhất là nhìn thấy trong kết quả thử nghiệm "10 đã qua, 0 thất bại, 1 bị bỏ qua" ít nhất là một số dấu hiệu cho thấy một điều gì đó đáng nghi với những người không quen thuộc với nó. Tôi thích @Ignorecách tiếp cận. Lý do chỉ sử dụng một nhận xét dường như không phải là một ý tưởng tốt đối với tôi là vì tôi không nghĩ mọi người sẽ thường mở các bài kiểm tra đơn vị để kiểm tra chúng (trừ khi chúng thất bại, hoặc (hy vọng) khi họ tự hỏi tại sao một cái gì đó bị bỏ qua ).
Thuyền trưởng Man

3

Tùy thuộc vào công cụ kiểm tra, bạn có thể sử dụng một omithoặc pendchức năng.

Ví dụ trong ruby:

gem 'test-unit', '>= 2.1.1'
require 'test/unit'

MYVERSION = '0.9.0' #Version of the class you test 


class Test_omit < Test::Unit::TestCase
  def test_omit
    omit('The following assertion fails - it will be corrected in the next release')
    assert_equal(1,2)
  end

  def test_omit_if
    omit_if(MYVERSION < '1.0.0', "Test skipped for version #{MYVERSION}")
    assert_equal(1,2)
  end

end

Các omitlệnh bỏ qua một bài kiểm tra, các omit_ifliên hợp gặt đập nó với một thử nghiệm - trong ví dụ của tôi, tôi kiểm tra số phiên bản và thực hiện các bài kiểm tra chỉ dành cho phiên bản mà tôi mong đợi các lỗi được giải quyết.

Đầu ra của ví dụ của tôi là:

Loaded suite test
Started
O
===============================================================================
The following assertion fails - it will be corrected in the next release [test_omit(Test_omit)]
test.rb:10:in `test_omit'
===============================================================================
O
===============================================================================
Test skipped for version 0.9.0 [test_omit_if(Test_omit)]
test.rb:15:in `test_omit_if'
===============================================================================


Finished in 0.0 seconds.

2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 2 omissions, 0 notifications
0% passed

Vì vậy, câu trả lời của tôi: Có, thực hiện các bài kiểm tra. Nhưng đừng nhầm lẫn một người kiểm tra có lỗi, nơi bạn biết nó sẽ thất bại.


2

Nếu lỗi mới xuất hiện trong đầu bạn và bạn có thời gian để viết bài kiểm tra đơn vị ngay bây giờ, thì tôi sẽ viết nó ngay bây giờ và đánh dấu nó là một lỗi đã biết để nó không tự làm hỏng bản dựng. Trình theo dõi lỗi của bạn phải được cập nhật để phản ánh rằng có một bài kiểm tra đơn vị hiện không thành công cho lỗi này để người được chỉ định sửa lỗi cuối cùng sẽ không viết lại. Điều này cho rằng mã lỗi không cần nhiều cấu trúc lại và API thay đổi đáng kể - nếu đó là trường hợp tốt hơn bạn không nên viết bài kiểm tra đơn vị cho đến khi bạn có ý tưởng tốt hơn về cách viết bài kiểm tra .


1

Câu trả lời là KHÔNG IMHO. Bạn không nên thêm một bài kiểm tra đơn vị cho lỗi cho đến khi bạn bắt đầu sửa lỗi và hơn là bạn sẽ viết (các) bài kiểm tra chứng minh lỗi đó và khi (các) bài kiểm tra đó bị lỗi theo báo cáo lỗi ( s) bạn sẽ đi và sửa mã thực tế để thực hiện (các) bài kiểm tra và lỗi sẽ được khắc phục và nó sẽ được khắc phục sau đó.

Trong thế giới của tôi, chúng ta sẽ có một trường hợp kiểm tra thủ công rằng các QE đã thất bại cho đến khi lỗi được sửa. Và chúng tôi là các nhà phát triển sẽ nhận thức được điều đó thông qua TC thất bại thủ công và thông qua trình theo dõi lỗi.

Lý do không thêm UT thất bại là đơn giản. UT là để phản hồi trực tiếp và xác nhận những gì tôi là một nhà phát triển hiện đang làm việc. Và UT được sử dụng trong hệ thống CI để đảm bảo rằng tôi đã không phá vỡ thứ gì đó ngoài ý muốn trong một số lĩnh vực mã khác cho mô-đun đó. Có các UT không cố ý cho một lỗi biết IMHO sẽ phản tác dụng và hoàn toàn sai.


0

Tôi cho rằng câu trả lời thực sự là, nó phụ thuộc. Hãy thực dụng về nó. Những gì nó viết bây giờ đạt được bạn? Có lẽ nó là tươi trong tâm trí của bạn?

Khi sửa lỗi, sẽ rất hợp lý khi chứng minh nó tồn tại bằng cách viết một bài kiểm tra đơn vị phơi bày lỗi. Sau đó, bạn sửa lỗi và kiểm tra đơn vị sẽ vượt qua.

Bạn có thời gian để viết bài kiểm tra đơn vị thất bại vừa nãy không? Có nhiều tính năng cấp bách hoặc lỗi cần được viết / sửa.

Giả sử bạn có phần mềm theo dõi lỗi có thẩm quyền với lỗi đã đăng nhập, thực sự không cần phải viết bài kiểm tra đơn vị bị lỗi ngay bây giờ .

Có thể cho rằng bạn có thể đưa ra một số nhầm lẫn nếu bạn giới thiệu một bài kiểm tra đơn vị bị lỗi trước khi bản phát hành đang diễn ra mà không sửa lỗi.


0

Tôi thường cảm thấy không yên tâm về việc đã biết những thất bại trong các bộ thử nghiệm, bởi vì quá dễ để danh sách phát triển theo thời gian hoặc cho những thất bại không liên quan trong các thử nghiệm tương tự bị loại bỏ như "mong đợi". Điều tương tự cũng xảy ra đối với những thất bại không liên tục - có thể có điều gì đó xấu xa đang che giấu mật mã. Tôi sẽ bỏ phiếu để viết bài kiểm tra cho mã như hiện tại và vì nó nên được sửa một lần nhưng nhận xét hoặc vô hiệu hóa bằng cách nào đó.

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.