# Lab 01 : Unit tests & coverage analysis


## Useful commands:

```
mvn test
mvn clean package
java -jar target/artifact-name.jar
mvn archetype:generate -DgroupId=org.ua.tqs -DartifactId=application
```

```
mvn clean test-compile
mvn clean test jacoco:report
```

<br>



# 1. Creating a Project in MVN

```
mvn archetype:generate -DgroupId=org.yourcompany.project -DartifactId=application
```


### MVN Command Execution Phases

| Phase     | Action                                                                 |
|-----------|------------------------------------------------------------------------|
| clean     | Delete `target` directory.                                             |
| validate  | Validate if the project is correct.                                    |
| compile   | Compile source code, classes stored in `target/classes`.               |
| test      | Run tests.                                                             |
| package   | Take the compiled code and package it (e.g., JAR, WAR).                |
| verify    | Run checks to verify the package is valid and meets quality criteria.  |
| install   | Install the package into the local repository.                         |
| deploy    | Copy the final package to the remote repository.                       |

<br>

Commands can be chained, e.g.:  
```
mvn clean test package
```

<br>

## 1.1 MVN Plugins 

### 1.1.1. Maven Help Plugin
- `mvn help:describe` → describes attributes of a plugin.  
- `mvn help:effective-pom` → displays effective POM as an XML for the current build, with the active profiles factored in. This is really useful when something goes wrong with the build and you need to verify that what you think you configured in the pom files is what Maven thinks is configured there.


### 1.1.2 Maven Dependency Plugin
- `mvn dependency:analyze` → analyzes dependencies, lists unused/outdated ones.  
- `mvn dependency:tree` → prints tree of dependencies, shows transitive dependencies and conflicts.  


<br>

## 1.2 JUnit Assertions 

- `assertEquals(expected, actual)`  
- `assertNotEquals(expected, actual)`  
- `assertTrue(condition)`  
- `assertFalse(condition)`  
- `assertNull(value)`  
- `assertNotNull(value)`  
- `assertArrayEquals(expectedArray, actualArray)`  
- `assertSame(expected, actual)`  
- `assertNotSame(expected, actual)`  
- `assertThrows(exceptionType, executable)`  

<br>

## 1.3 JaCoCo Coverage Testing
### Plugin Setup in `pom.xml`:
```xml
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.13</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>
```
<br>

###  Run Tests & Generate Report:
```
mvn clean test jacoco:report
```

Report generated at:  
```
target/site/jacoco/index.html
```

<br> 

### 1.3.1 JaCoCo Report Color Codes:
- **Red diamond**: no branches have been exercised
- **Yellow diamond**: the code is partially covered – some branches have not been exercised.
- **Green diamond**: all branches have been exercised

The same color code applies to the background color, but for lines coverage.

<br> 

### 1.3.2 Metrics

- **Line coverage** → % of code executed.  
- **Branch coverage** → % of branches tested (if/else, switch).  
- **Cyclomatic complexity** → # of independent paths.  


## 1.3.3 Enforcing Minimum Coverage

Add to `pom.xml` to ensure 90% coverage (excluding test classes):  

```xml
<execution>
    <id>check-coverage</id>
    <phase>verify</phase>
    <goals>
        <goal>check</goal>
    </goals>
    <configuration>
        <rules>
            <rule>
                <element>CLASS</element>
                <limits>
                    <limit>
                        <counter>LINE</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.90</minimum>
                    </limit>
                </limits>
                <excludes>
                    <exclude>**/*Test.class</exclude>
                    <exclude>**/test/**</exclude>
                </excludes>
            </rule>
        </rules>
    </configuration>
</execution>
```

Run:  
```
mvn clean verify
```

(to run ``mvn jacoco:check`` directly, add global <configuration> at plugin level) 

<br>

If the coverage is less than 90%, the build fails. Example error:  
```
[WARNING] Rule violated for class ua.tqs.MealsBookingService: lines covered ratio is 0.92, but expected minimum is 0.95
[ERROR] Failed to execute goal org.jacoco:jacoco-maven-plugin:0.8.13:check (jacoco-check) on project mealsbooking: Coverage checks have not been met. See log for details. -> [Help 1]
```

<br>

# 2. Classes notes:
- Tests are only as much of a safety net as you make them -> be through with what you're testing and how you're testing
- If a test fails -> check reports in `target/surefire-reports`
- Running `mvn clean test-compile` in VS Code enables the Testing tab (run, debug, coverage).  
  

### Why separate test methods?
Test methods should be writen in different functions:
- Each test has **one purpose** -> makes it easy to identify failures.  
- One failing assertion won't stop other tests (JUnit runs each @Test separately).
- JUnit shows which test failed (e.g., `testPushIncreasesSize`, `testPushAndPeek`)







