Repository: iluwatar/java-design-patterns
Issue: Arrange, Act, Assert pattern
Labels: epic: pattern
info: good first issue
type: feature

AAA is a way to structure your unit tests so they're easier to read, maintain, and enhance.

Reference: https://blog.ncrunch.net/post/arrange-act-assert-aaa-testing.aspx


Issue comments:
hi im a beginner. can u elaborate more? so what should be done?
For me it sounds just like a different name for Given-When-Then.
https://en.wikipedia.org/wiki/Given-When-Then
> For me it sounds just like a different name for Given-When-Then.
> https://en.wikipedia.org/wiki/Given-When-Then

I think you are right. You can also look at it as a reformulation of the Four-Phase Test pattern.
https://martinfowler.com/bliki/GivenWhenThen.html
@iluwatar , I'd like to take this
Ok @npczwh 

Pull request review comments:
We don't have an existing tag yet, but I would propose to use `Testing` here. Then we need to amend file https://github.com/iluwatar/java-design-patterns-web/blob/master/_data/tags.yml. See https://github.com/iluwatar/java-design-patterns/wiki/07.-Categories-and-Tags.
Changed in 882b569

Patch that resolved the issue:
diff --git a/arrange-act-assert/README.md b/arrange-act-assert/README.md
new file mode 100644
index 000000000000..02b7ee8b7398
--- /dev/null
+++ b/arrange-act-assert/README.md
@@ -0,0 +1,30 @@
+---
+layout: pattern
+title: Arrange/Act/Assert
+folder: arrange-act-assert
+permalink: /patterns/arrange-act-assert/
+categories: Idiom
+tags:
+ - Testing
+---
+
+## Also known as
+Given/When/Then
+
+## Intent
+The Arrange/Act/Assert (AAA) is a pattern for organizing unit tests.
+It breaks tests down into three clear and distinct steps:
+1. Arrange: Perform the setup and initialization required for the test.
+2. Act: Take action(s) required for the test.
+3. Assert: Verify the outcome(s) of the test.
+
+## Applicability
+Use Arrange/Act/Assert pattern when
+
+* you need to structure your unit tests so they're easier to read, maintain, and enhance. 
+
+## Credits
+
+* [Arrange, Act, Assert: What is AAA Testing?](https://blog.ncrunch.net/post/arrange-act-assert-aaa-testing.aspx)
+* [Bill Wake: 3A – Arrange, Act, Assert](https://xp123.com/articles/3a-arrange-act-assert/)
+* [Martin Fowler: GivenWhenThen](https://martinfowler.com/bliki/GivenWhenThen.html)
diff --git a/arrange-act-assert/etc/arrange-act-assert.urm.puml b/arrange-act-assert/etc/arrange-act-assert.urm.puml
new file mode 100644
index 000000000000..4b22d2a4e4bb
--- /dev/null
+++ b/arrange-act-assert/etc/arrange-act-assert.urm.puml
@@ -0,0 +1,11 @@
+@startuml
+package com.iluwatar.arrangeactassert {
+  class Cash {
+    - amount : int
+    ~ Cash(amount : int)
+    ~ count() : int
+    ~ minus(subtrahend : int) : boolean
+    ~ plus(addend : int)
+  }
+}
+@enduml
\ No newline at end of file
diff --git a/arrange-act-assert/pom.xml b/arrange-act-assert/pom.xml
new file mode 100644
index 000000000000..bb0387e7a6aa
--- /dev/null
+++ b/arrange-act-assert/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    The MIT License
+    Copyright © 2014-2019 Ilkka Seppälä
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>java-design-patterns</artifactId>
+    <groupId>com.iluwatar</groupId>
+    <version>1.23.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>arrange-act-assert</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/arrange-act-assert/src/main/java/com/iluwatar/arrangeactassert/Cash.java b/arrange-act-assert/src/main/java/com/iluwatar/arrangeactassert/Cash.java
new file mode 100644
index 000000000000..71269359ea58
--- /dev/null
+++ b/arrange-act-assert/src/main/java/com/iluwatar/arrangeactassert/Cash.java
@@ -0,0 +1,57 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.arrangeactassert;
+
+/**
+ * Arrange/Act/Assert (AAA) is a unit test pattern. In this simple example, we have a ({@link Cash})
+ * object for plus, minus and counting amount.
+ */
+public class Cash {
+
+  private int amount;
+
+  Cash(int amount) {
+    this.amount = amount;
+  }
+
+  //plus
+  void plus(int addend) {
+    amount += addend;
+  }
+
+  //minus
+  boolean minus(int subtrahend) {
+    if (amount >= subtrahend) {
+      amount -= subtrahend;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  //count
+  int count() {
+    return amount;
+  }
+}
diff --git a/pom.xml b/pom.xml
index b81cfe8d483e..97deda70313b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -184,6 +184,7 @@
         <module>combinator</module>
         <module>update-method</module>
         <module>leader-followers</module>
+        <module>arrange-act-assert</module>
     </modules>
 
     <repositories>


Test patch:
diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java
new file mode 100644
index 000000000000..d7841843db37
--- /dev/null
+++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java
@@ -0,0 +1,99 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.arrangeactassert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. It is a way to structure your
+ * tests so they're easier to read, maintain and enhance.
+ *
+ * <p>It breaks tests down into three clear and distinct steps:
+ * <p>1. Arrange: Perform the setup and initialization required for the test.
+ * <p>2. Act: Take action(s) required for the test.
+ * <p>3. Assert: Verify the outcome(s) of the test.
+ *
+ * <p>This pattern has several significant benefits. It creates a clear separation between a test's
+ * setup, operations, and results. This structure makes the code easier to read and understand. If
+ * you place the steps in order and format your code to separate them, you can scan a test and
+ * quickly comprehend what it does.
+ *
+ * <p>It also enforces a certain degree of discipline when you write your tests. You have to think
+ * clearly about the three steps your test will perform. But it makes tests more natural to write at
+ * the same time since you already have an outline.
+ *
+ * <p>In ({@link CashAAATest}) we have four test methods. Each of them has only one reason to
+ * change and one reason to fail. In a large and complicated code base, tests that honor the single
+ * responsibility principle are much easier to troubleshoot.
+ */
+public class CashAAATest {
+
+  @Test
+  public void testPlus() {
+    //Arrange
+    var cash = new Cash(3);
+    //Act
+    cash.plus(4);
+    //Assert
+    assertEquals(cash.count(), 7);
+  }
+
+  @Test
+  public void testMinus() {
+    //Arrange
+    var cash = new Cash(8);
+    //Act
+    var result = cash.minus(5);
+    //Assert
+    assertTrue(result);
+    assertEquals(cash.count(), 3);
+  }
+
+  @Test
+  public void testInsufficientMinus() {
+    //Arrange
+    var cash = new Cash(1);
+    //Act
+    var result = cash.minus(6);
+    //Assert
+    assertFalse(result);
+    assertEquals(cash.count(), 1);
+  }
+
+  @Test
+  public void testUpdate() {
+    //Arrange
+    var cash = new Cash(5);
+    //Act
+    cash.plus(6);
+    var result = cash.minus(3);
+    //Assert
+    assertTrue(result);
+    assertEquals(cash.count(), 8);
+  }
+}
diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java
new file mode 100644
index 000000000000..3f8c33d5ea95
--- /dev/null
+++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java
@@ -0,0 +1,59 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.arrangeactassert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * ({@link CashAAATest}) is an anti-example of AAA pattern. This test is functionally correct, but
+ * with the addition of new feature, it needs refactoring. There are an awful lot of steps in that
+ * test method, but it verifies the class' important behavior in just eleven lines. It violates the
+ * single responsibility principle. If this test method failed after a small code change, it might
+ * take some digging to discover why.
+ */
+public class CashAntiAAATest {
+
+  @Test
+  public void testCash() {
+    //initialize
+    var cash = new Cash(3);
+    //test plus
+    cash.plus(4);
+    assertEquals(cash.count(), 7);
+    //test minus
+    cash = new Cash(8);
+    assertTrue(cash.minus(5));
+    assertEquals(cash.count(), 3);
+    assertFalse(cash.minus(6));
+    assertEquals(cash.count(), 3);
+    //test update
+    cash.plus(5);
+    assertTrue(cash.minus(5));
+    assertEquals(cash.count(), 3);
+  }
+}