17

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);
Arman
  • 5,136
  • 3
  • 34
  • 36

5 Answers5

12

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.

Community
  • 1
  • 1
Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
  • I can see this technique is not widely used. Have you ever put it in practice in one of your real world production projects? – Arman Dec 22 '12 at 21:11
  • I've used it, but not in a particularly disciplined fashion. Just sometimes when I want to be sure that the action under test is what brings about the condition, sometimes I will write my tests this way. Not as a regular policy. – Carl Manaster Dec 22 '12 at 22:17
  • It's an interesting idea; I sometimes use it "informally" when I feel it's important to clarify what the preconditions of the test are. – Mathias Dec 23 '12 at 05:00
  • 8
    I like to call it Assume, so the pattern becomes Arrange-Assume-Act-Assert. (AAAA) – Patrick Szalapski Feb 13 '14 at 16:04
11

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.

Community
  • 1
  • 1
Akim
  • 8,469
  • 2
  • 31
  • 49
  • 3
    I've just checked a few thing over Internet and really seems like the Given-When-Then is the same Arrange-Act-Assert (for example [this](http://hadihariri.com/2012/04/11/what-bdd-has-taught-me/)). They semantically and logically look pretty similar. But the implementation differs exposing a fully explicit attributive way of testing. Nice :) – Arman Dec 21 '12 at 15:42
4

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.

guillaume31
  • 13,738
  • 1
  • 32
  • 51
  • Nice snapshot from history. I'm working on .net platform from the very first version and I can't remember if I've made use of one of those earliest mocking frameworks back that days. Neither one of my team members ever worked with. – Arman Dec 28 '12 at 08:55
1

when you are using parameterized testing then often you can move 'arranging' or 'given' part to parameters. but still, the principle remains

piotrek
  • 13,982
  • 13
  • 79
  • 165
1

Another common pattern used in unit testing is Four Phase Test Pattern:

  1. Setup
  2. Execute
  3. Check
  4. 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;
A.Robert
  • 304
  • 2
  • 7
  • 1
    You could call it Arrange-Act-Assert-Absterge :) Absterge was the only synonym for cleaning that started with an a that I could find. Maybe you could make an argument in favor of disAssemble, but that is just cheating I'd say :p – Sámal Rasmussen Mar 29 '17 at 11:05