Khi tôi sử dụng VS để tạo các bài kiểm tra đơn vị, tôi đã nhận Assert.Đối với các phương pháp thử được tạo và thường tôi thay đổi xác nhận để một điều gì đó khác khi tôi làm việc. Tôi sử dụng các dấu hỏi của Assert.Inconclusive trong kết quả kiểm tra như là dấu hiệu để nhanh chóng cho tôi biết những thử nghiệm mà tôi chưa hoàn thành.
Vâng, đó chỉ là cách tôi sử dụng nó. Từ tên của nó "Không kết luận", tôi đoán bạn có thể sử dụng để cho biết trạng thái không xác định của bạn miễn là bạn ghi lại ý nghĩa của nó. Tuy nhiên, từ mô tả phương pháp Average()
của bạn, tôi nghĩ rằng có lẽ thử nghiệm đơn vị của bạn không đủ nguyên tử để chỉ bao gồm một "đơn vị", một trường hợp cụ thể. Đôi khi, tôi viết 2 hoặc 3 phương pháp thử nghiệm đơn vị cho một phương pháp duy nhất. Hoặc bạn có thể phá vỡ phương pháp Average()
của bạn để các phương pháp nhỏ hơn bao gồm các trách nhiệm duy nhất. Bằng cách đó, bạn có thể kiểm tra đơn vị những phương pháp nhỏ hơn trước khi kiểm tra đơn vị bạn Average()
một.
Johannes,
Đây là cách tôi sẽ thực hiện các phương pháp Sum()
và Average()
.
public static class MyMath
{
private static void ValidateInput(ICollection<int> numbers)
{
if (numbers == null)
throw new ArgumentNullException("numbers", "Null input. Nothing to compute!");
if (numbers.Count == 0)
throw new ArgumentException("Input is empty. Nothing to compute!");
}
public static int Sum(int[] numbers)
{
ValidateInput(numbers);
var total = 0;
foreach (var number in numbers)
total += number;
return total;
}
public static double Average(int[] numbers)
{
ValidateInput(numbers);
return Sum(numbers)/numbers.Length;
}
}
Để đơn giản, tôi chỉ ném ArgumentException
ngoại lệ từ phương pháp ValidateInput(ICollection<int>)
. Bạn cũng có thể kiểm tra khả năng tràn và ném OverflowException
theo phương pháp ValidateInput(ICollection<int>)
.
Với điều đó đã nói, đây là cách tôi sẽ kiểm tra chức năng Average(int[])
.
[TestMethod]
public void AverageTest_GoodInput()
{
int[] numbers = {1, 2, 3};
const double expected = 2.0;
var actual = MyMath.Average(numbers);
Assert.AreEqual(expected, actual);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void AverageTest_NullInput()
{
int[] numbers = null;
MyMath.Average(numbers);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void AverageTest_EmptyInput()
{
var numbers = new int[0];
MyMath.Average(numbers);
}
Với các bài kiểm tra này, tôi có thể chắc chắn rằng khi tất cả các bài kiểm tra vượt qua, chức năng của tôi là chính xác. Vâng, ngoại trừ trường hợp tràn. Bây giờ tôi có thể quay trở lại phương pháp ValidateInput(ICollection<int>)
để thêm logic để kiểm tra tràn, sau đó thêm một thử nghiệm khác để mong đợi các OverflowException
được ném cho loại đầu vào gây ra tràn. Hoặc làm theo thứ tự ngược lại nếu bạn muốn tiếp cận bằng TDD.
Tôi hy vọng điều này sẽ giúp làm sáng tỏ ý tưởng.
bạn có thể vui lòng giải thích cách bạn sẽ tiếp cận điều này trong trường hợp rất đặc biệt này –
cảm ơn bạn rất nhiều. về bản chất bạn đang nói rằng không cần viết một bài kiểm tra rõ ràng cho Sum(), nhưng thử nghiệm nó thông qua Average(). Từ góc độ bao phủ mã, điều này cũng tạo ra kết quả tương tự. –
Tôi cũng sẽ viết các bài kiểm tra cho Sum(). Ai biết trong khoảnh khắc buồn ngủ của tôi, tôi có thể gõ '-' thay vì '/'. :) Với các test cho Sum() tại chỗ, nếu tôi có tất cả các test cho Sum() pass nhưng một số test cho Average() thất bại, tôi có thể rất chắc chắn rằng việc thực hiện cho Average() là sai. Tôi sẽ không thể đổ lỗi cho Sum() khiến cho Average() bị sai. :) – tranmq