The general question is are there alternative patterns to AAA for unit testing?
If, yes, would be very interesting to see some examples and hear about their pros and cons.
And as the simplest example of AAA test (in c#, using var for the sake of simplicity):
// Arranging
var annualSalary = 120000M;
var period = 3; // for a quarter profit
var calc = new SalaryCalculator();
// Acting
var result = calc.CalculateProfit(annualSalary, period);
// Assertion
Assert.IsEqual(40000, result);
I like something that is not so much an alternative to AAA, but rather a variation. I think of it as Arrange-Assert(not)-Act-Assert, but others have called it a Guard Assertion. The idea is to have an assertion that ensures the desired result of the Act is not already present before the act. There's a good discussion of it here.
There is another notation from Behavior-driven development: Given - When - Then. Examples for c# is SpecFlow and for Jasmin for JavaScript. Both resource are full of examples of using this notation. The GWT approach is typically used in a Behavior Driven Development and Aspect Oriented Programming.
Some of the earliest mocking frameworks (in the .Net world at least) forced you to use the Record/Replay pattern. I say force because I don't find it very natural or readable and there was no alternative back then.
This spawned a new race of isolation frameworks promoting the AAA form, which I find to be the most intent-revealing approach. More about this here.
when you are using parameterized testing then often you can move 'arranging' or 'given' part to parameters. but still, the principle remains
Another common pattern used in unit testing is Four Phase Test Pattern:
- Setup
- Execute
- Check
- Teardown
The first steps are essentially the same as in the AAA Pattern. However, I find the Four-Phase Pattern better suited to languages where you have to clean up after yourself, for example, C or C++. Step 4 (teardown) is where you free any allocated memory, or destroy objects you created for the test.
In situations where you do not allocate any memory, or a garbage collector takes care of deallocation, the fourth step goes unused most of the time, so it makes more sense to use the AAA Pattern.
In C++, for example, the above test might be:
// Setup
int annualSalary = 120000;
int period = 3; // for a quarter profit
int result;
SalaryCalculator calc = new SalaryCalculator();
// Execute
result = calc.CalculateProfit(annualSalary, period);
// Check
CHECK_EQUAL(40000, result);
// Teardown
delete calc;