Các số ma thuật có được chấp nhận trong các bài kiểm tra đơn vị nếu các số đó không có ý nghĩa gì không?


59

Trong các thử nghiệm đơn vị của tôi, tôi thường ném các giá trị tùy ý vào mã của mình để xem nó làm gì. Ví dụ: nếu tôi biết rằng foo(1, 2, 3)phải trả lại 17, tôi có thể viết điều này:

assertEqual(foo(1, 2, 3), 17)

Những con số này hoàn toàn tùy ý và không có ý nghĩa rộng hơn (ví dụ, chúng không phải là điều kiện biên, mặc dù tôi cũng thử nghiệm trên những điều đó). Tôi sẽ đấu tranh để đưa ra những cái tên hay cho những con số này, và viết một cái gì đó giống như const int TWO = 2;rõ ràng là không có ích. Viết các bài kiểm tra như thế này có ổn không, hay tôi nên tính các số đó thành các hằng số?

Trong Có phải tất cả các số ma thuật được tạo ra giống nhau? , chúng tôi đã học được rằng các con số ma thuật là ổn nếu ý nghĩa rõ ràng từ ngữ cảnh, nhưng trong trường hợp này, các con số thực sự không có ý nghĩa gì cả.


9
Nếu bạn đặt các giá trị vào và hy vọng có thể đọc lại các giá trị đó, tôi sẽ nói các số ma thuật là ổn. Vì vậy, nếu, giả sử, 1, 2, 3là các chỉ số mảng 3D nơi bạn đã lưu trữ giá trị trước đó 17, thì tôi nghĩ thử nghiệm này sẽ rất tệ (miễn là bạn cũng có một số thử nghiệm âm tính). Nhưng nếu đó là kết quả của một phép tính, bạn nên đảm bảo rằng bất kỳ ai đọc bài kiểm tra này sẽ hiểu tại sao foo(1, 2, 3)nên 17và số ma thuật có thể sẽ không đạt được mục tiêu đó.
Joe White

24
const int TWO = 2;thậm chí còn tồi tệ hơn là chỉ sử dụng 2. Nó phù hợp với từ ngữ của quy tắc với ý định vi phạm tinh thần của nó.
Đặc vụ_L

4
Một con số "không có nghĩa gì" là gì? Tại sao nó sẽ nằm trong mã của bạn nếu nó không có nghĩa gì?
Tim Grant

6
Chắc chắn rồi. Để lại một bình luận trước một loạt các thử nghiệm như vậy, ví dụ: "một lựa chọn nhỏ các ví dụ được xác định thủ công". Điều này, liên quan đến các thử nghiệm khác của bạn rõ ràng là ranh giới và ngoại lệ thử nghiệm, sẽ rõ ràng.
davidbak

5
Ví dụ của bạn là sai lệch - khi tên hàm của bạn thực sự foo, nó không có nghĩa gì cả, và các tham số cũng vậy. Nhưng trong thực tế, tôi khá chắc chắn chức năng không có tên đó, và các thông số không có tên bar1, bar2bar3. Làm một ví dụ thực tế hơn trong đó các tên ý nghĩa, sau đó sẽ có ý nghĩa hơn để thảo luận nếu các giá trị dữ liệu thử nghiệm cũng cần một tên.
Doc Brown

Câu trả lời:


81

Khi nào bạn thực sự có những con số không có ý nghĩa gì cả?

Thông thường, khi các số có bất kỳ ý nghĩa nào, bạn nên gán chúng cho các biến cục bộ của phương thức kiểm tra để làm cho mã dễ đọc hơn và tự giải thích. Tên của các biến ít nhất phải phản ánh ý nghĩa của biến đó, không nhất thiết là giá trị của nó.

Thí dụ:

const int startBalance = 10000;
const float interestRate = 0.05f;
const int years = 5;

const int expectedEndBalance = 12840;

assertEqual(calculateCompoundInterest(startBalance, interestRate, years),
            expectedEndBalance);

Lưu ý rằng biến đầu tiên không được đặt tên HUNDRED_DOLLARS_ZERO_CENT, nhưng startBalanceđể biểu thị ý nghĩa của biến đó là gì nhưng không phải giá trị của nó là đặc biệt.


3
@Kevin - bạn đang kiểm tra ngôn ngữ nào? Một số khung thử nghiệm cho phép bạn thiết lập các nhà cung cấp dữ liệu trả về một mảng các giá trị để thử nghiệm
HorusKol

10
Mặc dù tôi đồng ý với ý tưởng, hãy cẩn thận rằng thực tế này có thể giới thiệu các lỗi mới quá, như thế nào nếu bạn vô tình trích xuất một giá trị như 0.05fmột int. :)
Jeff Bowman

5
+1 - công cụ tuyệt vời. Chỉ vì bạn không quan tâm giá trị cụ thể là gì, điều đó không có nghĩa là nó vẫn không phải là một con số kỳ diệu ...
Robbie Dee

2
@PieterB: AFAIK đó là lỗi của C và C ++, đã chính thức hóa khái niệm về một constbiến.
Steve Jessop

2
Bạn đã đặt tên cho các biến của mình giống như các tham số được đặt tên của calculateCompoundInterestchưa? Nếu vậy, thì việc gõ thêm là một bằng chứng công việc mà bạn đã đọc tài liệu cho chức năng bạn đang kiểm tra hoặc ít nhất là sao chép tên do IDE của bạn cung cấp cho bạn. Tôi không chắc điều này cho người đọc biết bao nhiêu về mục đích của mã, nhưng nếu bạn chuyển các tham số theo thứ tự sai thì ít nhất họ có thể nói được ý định là gì.
Steve Jessop

20

Nếu bạn đang sử dụng các số tùy ý chỉ để xem những gì họ làm, thì những gì bạn thực sự tìm kiếm có lẽ là dữ liệu thử nghiệm được tạo ngẫu nhiên hoặc thử nghiệm dựa trên thuộc tính.

Ví dụ, Giả thuyết là một thư viện Python thú vị cho loại thử nghiệm này và dựa trên QuickCheck .

Hãy nghĩ về một bài kiểm tra đơn vị bình thường giống như sau:

  1. Thiết lập một số dữ liệu.
  2. Thực hiện một số thao tác trên dữ liệu.
  3. Khẳng định điều gì đó về kết quả.

Giả thuyết cho phép bạn viết các bài kiểm tra thay vì trông như thế này:

  1. Đối với tất cả các dữ liệu phù hợp với một số đặc điểm kỹ thuật.
  2. Thực hiện một số thao tác trên dữ liệu.
  3. Khẳng định điều gì đó về kết quả.

Ý tưởng là không ràng buộc bản thân với các giá trị của riêng bạn, nhưng chọn các giá trị ngẫu nhiên có thể được sử dụng để kiểm tra xem (các) chức năng của bạn có khớp với thông số kỹ thuật của chúng không. Một lưu ý quan trọng, các hệ thống này thường sẽ ghi nhớ bất kỳ đầu vào nào bị lỗi và sau đó đảm bảo rằng các đầu vào đó luôn được kiểm tra trong tương lai.

Điểm 3 có thể gây nhầm lẫn cho một số người vì vậy hãy làm rõ. Điều đó không có nghĩa là bạn đang khẳng định câu trả lời chính xác - điều này rõ ràng là không thể thực hiện đối với đầu vào tùy ý. Thay vào đó, bạn khẳng định một cái gì đó về một tính chất của kết quả. Ví dụ: bạn có thể khẳng định rằng sau khi thêm một cái gì đó vào danh sách, nó trở nên trống rỗng hoặc cây tìm kiếm nhị phân tự cân bằng thực sự được cân bằng (sử dụng bất kỳ tiêu chí nào mà cấu trúc dữ liệu cụ thể có).

Nhìn chung, việc tự mình chọn các số tùy ý có lẽ khá tệ - nó không thực sự bổ sung cả đống giá trị và gây nhầm lẫn cho bất kỳ ai đọc nó. Tự động tạo ra một loạt các dữ liệu thử nghiệm ngẫu nhiên và sử dụng hiệu quả đó là tốt. Tìm một giả thuyết hoặc thư viện giống như QuickCheck cho ngôn ngữ bạn chọn có lẽ là cách tốt hơn để thực hiện mục tiêu của bạn trong khi vẫn có thể hiểu được cho người khác.


11
Thử nghiệm ngẫu nhiên có thể tìm thấy các lỗi khó sinh sản nhưng kiểm tra ngẫu nhiên hầu như không tìm thấy các lỗi có thể lặp lại. Hãy chắc chắn để nắm bắt bất kỳ lỗi thử nghiệm với một trường hợp thử nghiệm tái sản xuất cụ thể.
JBRWilkinson

5
Và làm thế nào để bạn biết rằng bài kiểm tra đơn vị của bạn không bị lỗi khi bạn "khẳng định điều gì đó về kết quả" (trong trường hợp này, tính toán lại foomáy tính là gì ) ...? Nếu bạn chắc chắn 100% mã của bạn đưa ra câu trả lời đúng, thì bạn sẽ chỉ đưa mã đó vào chương trình và không kiểm tra nó. Nếu bạn không phải, thì bạn cần phải kiểm tra thử nghiệm và tôi nghĩ mọi người đều thấy nơi này sẽ diễn ra.

2
Vâng, nếu bạn chuyển đầu vào ngẫu nhiên vào một chức năng, bạn phải biết đầu ra sẽ là gì để có thể khẳng định rằng nó hoạt động chính xác. Với các giá trị kiểm tra cố định / được chọn, tất nhiên bạn có thể xử lý bằng tay, v.v. nhưng chắc chắn bất kỳ phương pháp tự động nào để phát hiện nếu kết quả đúng đều phải chịu các vấn đề chính xác giống như chức năng bạn đang kiểm tra. Bạn có thể sử dụng triển khai mà bạn có (mà bạn không thể vì bạn đang kiểm tra xem nó có hoạt động không) hoặc bạn viết một triển khai mới có khả năng là lỗi (hoặc khác là bạn sử dụng nhiều khả năng là đúng ).
Chris

7
@NajibIdrissi - không nhất thiết phải như vậy. Ví dụ, bạn có thể kiểm tra rằng áp dụng nghịch đảo của thao tác bạn đang kiểm tra vào kết quả sẽ trả về giá trị ban đầu bạn đã bắt đầu. Hoặc bạn có thể kiểm tra các bất biến dự kiến ​​(ví dụ: đối với tất cả các tính toán lãi suất theo dngày, tính toán vào các dngày + 1 tháng sẽ là tỷ lệ phần trăm hàng tháng được biết cao hơn), v.v.
Jules

12
@Chris - Trong nhiều trường hợp, kiểm tra kết quả là chính xác dễ dàng hơn tạo kết quả. Mặc dù điều này không đúng trong mọi trường hợp, nhưng có rất nhiều nơi. Ví dụ: việc thêm một mục vào cây nhị phân cân bằng sẽ dẫn đến một cây mới cũng được cân bằng ... dễ kiểm tra, khá khó để thực hiện trong thực tế.
Jules

11

Tên kiểm tra đơn vị của bạn sẽ cung cấp hầu hết các bối cảnh. Không phải từ các giá trị của hằng số. Tên / tài liệu cho một bài kiểm tra nên đưa ra bối cảnh và giải thích phù hợp về bất kỳ con số ma thuật nào có trong bài kiểm tra.

Nếu điều đó là không đủ, một chút tài liệu sẽ có thể cung cấp nó (cho dù thông qua tên biến hoặc chuỗi doc). Hãy nhớ rằng hàm tự nó có các tham số hy vọng có tên có ý nghĩa. Sao chép chúng vào bài kiểm tra của bạn để đặt tên cho các đối số là khá vô nghĩa.

Và cuối cùng, nếu sự không rõ ràng của bạn đủ phức tạp đến mức khó / không thực tế, bạn có thể có quá nhiều chức năng và có thể xem xét tại sao lại như vậy.

Bạn càng viết chậm các bài kiểm tra, mã thực tế của bạn sẽ càng tệ. Nếu bạn cảm thấy cần phải đặt tên cho các giá trị thử nghiệm của mình để làm cho thử nghiệm rõ ràng, nó gợi ý mạnh mẽ phương pháp thực tế của bạn cần đặt tên và / hoặc tài liệu tốt hơn. Nếu bạn thấy cần phải đặt tên hằng trong các bài kiểm tra, tôi sẽ xem xét lý do tại sao bạn cần điều này - có thể vấn đề không phải là bản thân bài kiểm tra mà là việc thực hiện


Câu trả lời này dường như là về khó khăn trong việc suy ra mục đích của một bài kiểm tra trong khi câu hỏi thực tế là về số ma thuật trong các tham số phương pháp ...
Robbie Dee

@RobbieDee tên / tài liệu cho một bài kiểm tra nên đưa ra bối cảnh và giải thích phù hợp về bất kỳ con số ma thuật nào có trong bài kiểm tra. Nếu không, hãy thêm tài liệu hoặc đổi tên bài kiểm tra để rõ ràng hơn.
enderland

Nó vẫn sẽ tốt hơn để cung cấp cho các tên số ma thuật. Nếu số lượng tham số thay đổi, rủi ro tài liệu sẽ trở nên lỗi thời.
Robbie Dee

1
@RobbieDee hãy nhớ rằng chính hàm này có các tham số hy vọng có tên có ý nghĩa. Sao chép chúng vào bài kiểm tra của bạn để đặt tên cho các đối số là khá vô nghĩa.
enderland

"Hy vọng" hả? Tại sao không chỉ viết mã đúng cách và loại bỏ những gì có vẻ là một con số ma thuật như Philipp đã vạch ra ...
Robbie Dee

9

Điều này phụ thuộc rất nhiều vào chức năng bạn đang thử nghiệm. Tôi biết rất nhiều trường hợp các số riêng lẻ không có ý nghĩa đặc biệt, nhưng toàn bộ trường hợp kiểm tra được xây dựng chu đáo và do đó có một ý nghĩa cụ thể. Đó là những gì người ta nên tài liệu theo một cách nào đó. Ví dụ: nếu foothực sự là một phương thức testForTrianglequyết định xem ba số có thể là độ dài hợp lệ của các cạnh của một tam giác hay không, các thử nghiệm của bạn có thể trông như thế này:

// standard triangle with area >0
assertEqual(testForTriangle(2, 3, 4), true);

// degenerated triangle, length of two edges match the length of the third
assertEqual(testForTriangle(1, 2, 3), true);  

// no triangle
assertEqual(testForTriangle(1, 2, 4), false); 

// two sides equal
assertEqual(testForTriangle(2, 2, 3), true);

// all three sides equal
assertEqual(testForTriangle(4, 4, 4), true);

// degenerated triangle / point
assertEqual(testForTriangle(0, 0, 0), true);  

vân vân Bạn có thể cải thiện điều này và biến các bình luận thành một tham số tin nhắn assertEqualsẽ được hiển thị khi thử nghiệm thất bại. Sau đó, bạn có thể cải thiện điều này hơn nữa và cấu trúc lại nó thành một thử nghiệm dựa trên dữ liệu (nếu khung thử nghiệm của bạn hỗ trợ điều này). Tuy nhiên, bạn có lợi cho mình nếu bạn ghi chú vào mã tại sao bạn chọn con số này và hành vi nào bạn đang thử nghiệm với từng trường hợp riêng lẻ.

Tất nhiên, đối với các hàm khác, các giá trị riêng cho các tham số có thể quan trọng hơn, vì vậy sử dụng tên hàm vô nghĩa như fookhi hỏi cách xử lý ý nghĩa của tham số có lẽ không phải là ý tưởng tốt nhất.


Giải pháp hợp lý.
dùng1725145

6

Tại sao chúng ta muốn sử dụng Hằng có tên thay vì số?

  1. DRY - Nếu tôi cần giá trị ở 3 vị trí, tôi chỉ muốn xác định nó một lần, vì vậy tôi có thể thay đổi nó ở một nơi, nếu nó thay đổi.
  2. Đưa ra ý nghĩa cho những con số.

Nếu bạn viết một số bài kiểm tra đơn vị, mỗi bài kiểm tra có 3 Số (startBalance, lãi, năm) - tôi sẽ chỉ đóng gói các giá trị vào bài kiểm tra đơn vị dưới dạng các biến cục bộ. Phạm vi nhỏ nhất nơi họ thuộc về.

testBigInterest()
  var startBalance = 10;
  var interestInPercent = 100
  var years = 2
  assert( calcCreditSum( startBalance, interestInPercent, years ) == 40 )

testSmallInterest()
  var startBalance = 50;
  var interestInPercent = .5
  var years = 1
  assert( calcCreditSum( startBalance, interestInPercent, years ) == 50.25 )

Nếu bạn sử dụng một ngôn ngữ cho phép các tham số được đặt tên, điều này tất nhiên là thừa. Ở đó tôi chỉ đóng gói các giá trị thô trong lệnh gọi phương thức. Tôi không thể tưởng tượng bất kỳ tái cấu trúc làm cho tuyên bố này ngắn gọn hơn:

testBigInterest()
  assert( calcCreditSum( startBalance:       10
                        ,interestInPercent: 100
                        ,years:               2 ) = 40 )

Hoặc sử dụng Khung kiểm tra, sẽ cho phép bạn xác định các trường hợp thử nghiệm ở một số định dạng mảng hoặc Bản đồ:

testcases = { {
                Name: "BigInterest"
               ,StartBalance:       10
               ,InterestInPercent: 100
               ,Years:               2
              }
             ,{ 
                Name: "SmallInterest"
               ,StartBalance:       50
               ,InterestInPercent:  .5
               ,Years:               1
              }
            }

3

... nhưng trong trường hợp này, những con số thực sự không có ý nghĩa gì cả

Các số đang được sử dụng để gọi một phương thức nên chắc chắn tiền đề trên là không chính xác. Bạn có thể không quan tâm những con số là gì nhưng đó là bên cạnh điểm. Có, bạn có thể suy ra những con số được sử dụng cho một số thuật sĩ IDE nhưng sẽ tốt hơn nhiều nếu bạn chỉ đưa ra các tên giá trị - ngay cả khi chúng chỉ khớp với các tham số.


1
Tuy nhiên, điều này không nhất thiết đúng - như trong ví dụ về bài kiểm tra đơn vị gần đây nhất mà tôi đã viết ( assertEqual "Returned value" (makeKindInt 42) (runTest "lvalue_operators")). Trong ví dụ này, 42chỉ là một giá trị giữ chỗ được tạo bởi mã trong tập lệnh kiểm tra có tên lvalue_operatorsvà sau đó được kiểm tra khi nó được trả về bởi tập lệnh. Nó hoàn toàn không có ý nghĩa gì, ngoài việc cùng một giá trị xảy ra ở hai nơi khác nhau. Điều gì sẽ là một tên thích hợp ở đây mà thực tế mang lại bất kỳ ý nghĩa hữu ích?
Jules

3

Nếu bạn muốn kiểm tra một hàm thuần túy trên một tập hợp các đầu vào không có điều kiện biên, thì bạn gần như chắc chắn muốn kiểm tra nó trên một loạt các bộ đầu vào không (và) điều kiện biên. Và với tôi điều đó có nghĩa là cần có một bảng các giá trị để gọi hàm và một vòng lặp:

struct test_foo_values {
    int bar;
    int baz;
    int blurf;
    int expected;
};
const struct test_foo_values test_foo_with[] = {
   { 1, 2, 3, 17 },
   { 2, 4, 9, 34 },
   // ... many more here ...
};

for (size_t i = 0; i < ARRAY_SIZE(test_foo_with); i++) {
    const struct test_foo_values *c = test_foo_with[i];
    assertEqual(foo(c->bar, c->baz, c->blurf), c->expected);
}

Các công cụ như những gợi ý trong câu trả lời của Dannnno có thể giúp bạn xây dựng bảng giá trị để kiểm tra. bar, bazblurfnên được thay thế bằng các tên có ý nghĩa như được thảo luận trong câu trả lời của Philipp .

(Đáng tranh cãi nguyên tắc chung ở đây: số không phải lúc nào "con số ma thuật" mà cần tên, thay vào đó, số có thể là dữ liệu Nếu nó sẽ làm cho tinh thần để đưa con số của bạn thành một mảng, có lẽ một loạt các hồ sơ, sau đó họ có thể dữ liệu. Ngược lại, nếu bạn nghi ngờ bạn có thể có dữ liệu trên tay, hãy xem xét đưa nó vào một mảng và có được nhiều dữ liệu hơn.)


1

Các thử nghiệm khác với mã sản xuất và, ít nhất là trong các thử nghiệm đơn vị được viết bằng Spock, ngắn và đến thời điểm đó, tôi không có vấn đề gì khi sử dụng hằng số ma thuật.

Nếu một bài kiểm tra dài 5 dòng và tuân theo sơ đồ đã cho / khi / sau đó, việc trích xuất các giá trị đó vào các hằng số sẽ chỉ làm cho mã dài hơn và khó đọc hơn. Nếu logic là "Khi tôi thêm người dùng có tên Smith, tôi sẽ thấy người dùng Smith được trả về trong danh sách người dùng", không có lý do gì để trích xuất "Smith" thành hằng số.

Tất nhiên điều này áp dụng nếu bạn có thể dễ dàng khớp các giá trị được sử dụng trong khối "đã cho" (thiết lập) với các giá trị được tìm thấy trong các khối "khi" và "sau đó". Nếu thiết lập thử nghiệm của bạn được tách biệt (bằng mã) khỏi vị trí dữ liệu được sử dụng, thì có thể sử dụng các hằng số tốt hơn. Nhưng vì các bài kiểm tra là khép kín tốt nhất, thiết lập thường gần với nơi sử dụng và trường hợp đầu tiên được áp dụng, có nghĩa là hằng số ma thuật hoàn toàn có thể chấp nhận được trong trường hợp này.


1

Trước hết, hãy đồng ý rằng bài kiểm tra đơn vị của Google, thường được sử dụng để bao quát tất cả các bài kiểm tra tự động mà một lập trình viên viết, và việc tranh luận xem mỗi bài kiểm tra nên được gọi là gì là vô nghĩa.

Tôi đã làm việc trên một hệ thống mà phần mềm đã lấy rất nhiều đầu vào và tìm ra một giải pháp LỚN mà phải thực hiện một số hạn chế, trong khi tối ưu hóa các số khác. Không có câu trả lời đúng, vì vậy phần mềm chỉ cần đưa ra câu trả lời hợp lý.

Nó đã làm điều này bằng cách sử dụng rất nhiều số ngẫu nhiên để có được điểm bắt đầu, sau đó sử dụng một người leo núi đồi đồi để cải thiện kết quả. Điều này đã được chạy nhiều lần, chọn kết quả tốt nhất. Một trình tạo số ngẫu nhiên có thể được tạo mầm, để nó luôn đưa ra các số giống nhau theo cùng một thứ tự, do đó nếu thử nghiệm đặt một hạt giống, chúng ta biết rằng kết quả sẽ giống nhau trên mỗi lần chạy.

Chúng tôi đã có rất nhiều bài kiểm tra đã làm như trên và kiểm tra xem kết quả có giống nhau không, điều này cho chúng tôi biết rằng chúng tôi đã không thay đổi những gì phần hệ thống đã làm do nhầm lẫn trong khi tái cấu trúc, v.v. Nó không cho chúng tôi biết gì về tính đúng đắn của những gì một phần của hệ thống đã làm.

Các thử nghiệm này rất tốn kém để duy trì, vì bất kỳ thay đổi nào đối với mã tối ưu hóa sẽ phá vỡ các thử nghiệm, nhưng họ cũng tìm thấy một số lỗi trong mã lớn hơn nhiều đã xử lý trước dữ liệu và xử lý hậu quả các kết quả.

Khi chúng tôi chế nhạo cơ sở dữ liệu, bạn có thể gọi các bài kiểm tra này là đơn vị kiểm tra đơn giản, nhưng đơn vị này thì khá lớn.

Thông thường khi bạn đang làm việc trên một hệ thống không có kiểm tra, bạn sẽ làm một cái gì đó giống như trên, để bạn có thể xác nhận việc tái cấu trúc của mình không thay đổi đầu ra; hy vọng các bài kiểm tra tốt hơn được viết cho mã mới!


1

Tôi nghĩ trong trường hợp này, các số nên được gọi là Số tùy ý, thay vì Số ma thuật, và chỉ nhận xét dòng này là "trường hợp kiểm tra tùy ý".

Chắc chắn, một số Số ma thuật cũng có thể tùy ý, như đối với các giá trị "xử lý" duy nhất (tất nhiên phải được thay thế bằng các hằng số được đặt tên), nhưng cũng có thể là các hằng số được tính toán trước như "tốc độ của một con chim sẻ châu Âu không có lông trong mỗi hai tuần", trong đó giá trị số được cắm mà không có ý kiến ​​hoặc bối cảnh hữu ích.


0

Tôi sẽ không mạo hiểm khi nói có / không dứt khoát, nhưng đây là một số câu hỏi bạn nên tự hỏi khi quyết định liệu nó có ổn hay không.

  1. Nếu những con số không có ý nghĩa gì, tại sao chúng lại ở đó ngay từ đầu? Họ có thể được thay thế bởi một cái gì đó khác? Bạn có thể xác minh dựa trên các cuộc gọi và luồng phương thức thay vì xác nhận giá trị không? Hãy xem xét một cái gì đó giống như verify()phương thức của Mockito để kiểm tra xem các cuộc gọi phương thức nhất định có được thực hiện để giả định các đối tượng hay không thay vì thực sự khẳng định một giá trị.

  2. Nếu những con số làm nghĩa một cái gì đó, sau đó họ nên được gán cho biến đó được đặt tên một cách thích hợp.

  3. Viết số 2như TWOcó thể hữu ích trong những bối cảnh nhất định, và không quá nhiều trong những bối cảnh khác.

    • Ví dụ: assertEquals(TWO, half_of(FOUR))có ý nghĩa với người đọc mã. Nó ngay lập tức rõ ràng những gì bạn đang thử nghiệm.
    • Tuy nhiên, nếu thử nghiệm của bạn là assertEquals(numCustomersInBank(BANK_1), TWO), thì điều này không ý nghĩa nhiều lắm. Tại sao không BANK_1có hai khách hàng? Có gì chúng tôi đang thử nghiệm cho?
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.