人非圣贤孰能无过
,归根结底,代码是人写的,Bug
终究是无法避免的。测试的目的是为了尽早发现问题,尽量减少Bug
数量。
Smoke test
Unit Tests
Moq
和nSubstitute
Integration Tests
Functional Tests
Subcutaneous Tests
UI
下的测试Load Tests
Stress Tests
CPU
,Network
,Memory
指标要
不要
不好的
[Test]
public void ShouldAddTwoNumbers()
{
var calculator = new Calculator();
var result = calculator.Sum(10, 11);
Assert.Equal(21, result);
}
// The method to test in class Calculator ...
public int Sum(int x, int y)
{
throw new NotImplementedException();
}
好的
[Test]
public void ShouldAddTwoNumbers()
{
var calculator = new Calculator();
var result = calculator.Sum(10, 11);
Assert.Equal(21, result);
}
// The method to test in class Calculator ...
public int Sum(int x, int y)
{
return 0;//返回一个值让不通过
}
Bug
如果通过单元测试发现一个Bug
, 即单元测试显示红灯。重构代买,单元测试通过,显示绿色。于是,单元测试起到了帮助代码重构的作用。
NUnit
: 是.NET
开源的、被认可的测试框架,有UI
XUnit
: 来之NUnit
作者,最新的,鼓励TDD
的开发方式,甚至.NET Core
团队也在使用MSTest
: 微软的测试框架,无法在build server
跑CI/CD
监控源代码,一旦有变化,检查、构建、自动测试、发送报告等。
MethodName_StateUnderTest_ExpectedBehavior
isAdult_AgeLessThan18_False
withdrawMoney_InvalidAccount_ExceptionThrown
admitStudent_MissingMandatoryFields_FailToAdmit
MethodName_ExpectedBehavior_StateUnderTest
test[Feature being tested]
testIsNotAnAdultIfAgeLessThan18
testFailToWithdrawMoneyIfAccountIsInvalid
Feature to be tested
IsNotAnAdultIfAgeLessThan18
FailToWithdrawMoneyIfAccountIsInvalid
Should_ExpectedBehaviour_When_StateUnderTest
Should_ThrowException_When_AgeLessThan18
Should_FailToWithdrawMoney_ForInvalidAccount
When_StateUnderTest_Expect_ExpectedBehavior
When_AgeLessThan18_Expect_isAdultAsFalse
When_InvalidAccount_Expect_WithdrawMoneyToFail
Given_Preconditions_When_StateUnderTest_Then_ExpectedBehavior
Given_UserIsAuthenticated_When_InvalidAccountNumberIsUsedToWithdrawMoney_Then_TransactionsWillFail
AAA
[TestMethod]
public void TestRegisterPost_ValidUser_ReturnsRedirect()
{
// Arrange
AccountController controller = GetAccountController();
RegisterModel model = new RegisterModel()
{
UserName = "someUser",
Email = "goodEmail",
Password = "goodPassword",
ConfirmPassword = "goodPassword"
};
// Act
ActionResult result = controller.Register(model);
// Assert
RedirectToRouteResult redirectResult = (RedirectToRouteResult)result;
Assert.AreEqual("Home", redirectResult.RouteValues["controller"]);
Assert.AreEqual("Index", redirectResult.RouteValues["action"]);
}
被测代码,数量越大越难测,很有必要使用单元测试。
public decimal CalculateTotal(List<myitem> items)
{
decimal total = 0.0m;
foreach(MyItem i in items)
{
total += i.UnitPrice * (i - i.Discount);
}
return total;
}
Test Explorer
的使用不好
while ((ActiveThreads > 0 || AssociationsQueued > 0) && (IsRegistered || report.TotalTargets <= 1000 )
&& (maxNumPagesToScan == -1 || report.TotalTargets < maxNumPagesToScan) && (!CancelScan))
好的
while (!HasFinishedInitializing (ActiveThreads, AssociationsQueued, IsRegistered,
report.TotalTargets, maxNumPagesToScan, CancelScan))
Selenium
进行Web
测试