A unit test is a piece of code written by a developer that exercises a very small, specific area of functionality of the code being tested.
"Program testing can be used to show the presence of bugs, but never to show their absence!"
Edsger Dijkstra, [1972]
“A unit test is a piece of code that invokes a unit of work and checks one specific end result of that unit of work. If the assumptions on the end result turn out to be wrong, the unit test has failed. A unit test’s scope can span as little as a method or as much as multiple classes.”
“A unit of work is the sum of actions that take place between the invocation of a public method in the system and a single noticeable end result by a test of that system. …”
Software Development Lifecycle
QUESTION:
Who’s responsible for the quality of a software system?
ANSWERS:
- QA Engineer
- Software Engineer
- Everyone
- No one
Right answer – everybody in the team, not just QAs. Developers are responsible for the code to run correctly always BEFORE committing.
Unit Testing is NOT Test Driven Development (TDD)
and
Test Driven Development is NOT only Unit Testing
TDD, Test-first development and Test-driven-design are different concepts that rely on Unit Testing.
But they are not the same and should not be confused! We will not cover TDD here.
TDD is a very advanced practice and skill
Even if looks relatively simple process to you
Reasons not to write unit tests
"Writing tests is too hard."
"Testing is not my job."
"My code is too simple for tests."
"I don't have enough time to write tests."
"I don't know how to write tests."
Most companies that have lengthy software development lifecycle adopt some version of unit testing process.
int Sum(int[] array)
{
int sum = 0;
for (int i = 0; i < array.Length; i++)
sum += array[i];
return sum;
}
void Sum_Should()
{
if (Sum(new int[]{ 1, 2 }) != 3)
throw new TestFailedException("1 + 2 != 3");
if (Sum(new int[]{ -2 }) != -2)
throw new TestFailedException("-2 != -2");
if (Sum(new int[]{ }) != 0)
throw new TestFailedException("0 != 0");
}
(examples are with MSTest syntax)
Assert.AreEqual(expectedValue, actualValue, "Error message.");
Assert.AreEqual(expected_value, actual_value [,message])
Assert.AreSame(expected_object, actual_object [,message])
Assert.IsTrue(condition)
Assert.IsFalse(condition)
Assert.Fail(message)
Assert.IsNull(object [,message])
Assert.IsNotNull(object [,message])
public class Account
{
private decimal balance;
public void Deposit(decimal amount)
{
this.balance += amount;
}
public void Withdraw(decimal amount)
{
this.balance -= amount;
}
public void TransferFunds_Should_Condition(
Account destination, decimal amount) { … }
public decimal Balance { … }
}
[TestMethod]
public void TestDeposit() // TODO: Improve test name
{
// Arrange
BankAccount account = new BankAccount();
// Act
account.Deposit(125.0);
// Assert
Assert.AreEqual(125.0, account.Balance, "Balance is wrong.");
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class AccountShould
{
[TestMethod]
public void TransferFunds_ShouldUpdateBothAccountBalances_WhenInvoked()
{
// Arrange
Account source = new Account(200.00M);
Account dest = new Account(150.00M);
// Act
source.TransferFunds(dest, 100.00M);
// Assert
Assert.AreEqual(100.00M, source.Balance);
Assert.AreEqual(250.00M, dest.Balance);
}
}
using NUnit.Framework;
[TestFixture]
public class AccountTest
{
[Test]
public void TransferFunds_ShouldUpdateBothAccountBalances_WhenInvoked()
{
// Arrange
Account source = new Account(200.00M);
Account dest = new Account(150.00M);
// Act
source.TransferFunds(dest, 100.00M);
// Assert
Assert.AreEqual(100.00M, source.Balance);
Assert.AreEqual(250.00M, dest.Balance);
}
}
public string ReverseString(string text)
{
StringBuilder sBuilder = new StringBuilder();
for (int i = text.Length - 1; i >= 0; i--)
{
sBuilder.Append(text[i]);
}
return sBuilder.ToString();
}
[Test]
void Sum_ShouldThrow_WhenFirstPassedNumberIsNegative()
{
Assert.ShouldThrow(() => Sum(-1, 1, 2));
}
int Sum(int a, int b) -> return sum of a and b
public void Sum_AddsOneAndTwo()
{
int result = Sum(1, 2);
Assert.AreEqual(4, result, "Bad sum");
}
void Sum_Test()
{
Assert.AreEqual(3, Sum(1001, 1, 2));
Assert.AreEqual(3, Sum(1, 1001, 2));
Assert.AreEqual(3, Sum(1, 2, 1001));
}