Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions phpunit/.github/workflows/testomatio.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: PHPUnit Tests with Testomat.io

on:
push:
branches:
- master
- main
pull_request:
branches:
- master
- main

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, xml, ctype, json
coverage: none

- name: Validate composer.json
run: composer validate --strict

- name: Cache Composer packages
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-

- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-interaction

- name: Run PHPUnit tests
env:
TESTOMATIO: ${{ secrets.TESTOMATIO }}
run: ./vendor/bin/phpunit
7 changes: 7 additions & 0 deletions phpunit/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/vendor/
/build/
/.phpunit.cache/
.phpunit.result.cache
composer.lock
.env
.DS_Store
243 changes: 243 additions & 0 deletions phpunit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
# PHPUnit Example with Testomat.io

This is an example project demonstrating how to integrate PHPUnit tests with Testomat.io using JUnit XML reports.

## 🛠️ Tech Stack

| Tool | Description |
|------|-------------|
| [PHPUnit](https://phpunit.de/) | PHP testing framework |
| [Testomat.io](https://testomat.io/) | Test management system |
| PHP 8.0+ | Programming language |

## Requirements

### Required
- **PHP 8.0 or higher** - For running PHPUnit tests
- **[Composer](https://getcomposer.org)** - PHP package manager for installing dependencies

### Optional (for Testomat.io integration)
- **Testomat.io API Key** - specific to your project

### Installation Instructions

#### Installing PHP

**macOS:**
```bash
# Using Homebrew
brew install php

# Verify installation
php --version
```

**Ubuntu/Debian:**
```bash
sudo apt update
sudo apt install php php-mbstring php-xml php-curl

# Verify installation
php --version
```

**Windows:**
- Download PHP from [windows.php.net](https://windows.php.net/download/)
- Or use [XAMPP](https://www.apachefriends.org/) / [WAMP](https://www.wampserver.com/)

#### Installing Composer

**macOS/Linux:**
```bash
# Download and install
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer

# Verify installation
composer --version
```

**Windows:**
- Download installer from [getcomposer.org](https://getcomposer.org/download/)
- Run the installer and follow instructions

#### Installing Node.js

**macOS:**
```bash
# Using Homebrew
brew install node

# Verify installation
node --version
npm --version
```

**Ubuntu/Debian:**
```bash
# Using NodeSource repository
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Verify installation
node --version
npm --version
```

**Windows:**
- Download installer from [nodejs.org](https://nodejs.org/)
- Run the installer and follow instructions

## ⚙️ Installation

Clone the examples repository and navigate to the phpunit directory:

```bash
git clone https://github.com/testomatio/examples.git
cd examples/phpunit
```

Install dependencies:

```bash
composer install
```

## 🏃‍♂️ Running Tests

Run all tests:

```bash
./vendor/bin/phpunit
```

Run tests with verbose output:

```bash
./vendor/bin/phpunit --testdox
```

Run specific test file:

```bash
./vendor/bin/phpunit tests/CalculatorTest.php
```

## 📊 Integration with Testomat.io

This project uses the native **Testomat.io PHP Reporter** to report results directly.

### Step 1: Install Reporter

The reporter is included in `composer.json`. If you need to install it manually:

```bash
composer require --dev testomatio/reporter
```

### Step 2: Configure PHPUnit

The reporter is enabled in `phpunit.xml`:

```xml
<listeners>
<listener class="Testomatio\Reporter\PHPUnit" file="vendor/testomatio/reporter/src/PHPUnit.php" />
</listeners>
```

### Step 3: Run Tests and Report Results

Run tests passing the `TESTOMATIO` environment variable:

```bash
TESTOMATIO={your-api-key} ./vendor/bin/phpunit
```

### Step 4: Import Test Structure

To import test structure into Testomat.io:

```bash
TESTOMATIO={your-api-key} ./vendor/bin/phpunit --list-tests
```
Note: The reporter captures the list of tests and uploads them when the API key is present.

> **Environment Variables**: It is recommended to store the Testomat.io API Key as an environment variable and never save it in source code.

### Note on Data Providers

PHPUnit's data providers create multiple test executions from a single test method. In this example:
- PHPUnit executes **22 tests** (13 test methods with data provider variations)
- JUnit XML report contains all 22 test case entries
- Testomat.io may show fewer tests due to how it parses nested `<testsuite>` elements for data providers

This is expected behavior when using data providers with JUnit XML format. All test results are captured correctly.

## 📝 Test Examples

This project includes:

### CalculatorTest.php
- Basic arithmetic operations (add, subtract, multiply, divide)
- Exception handling (division by zero)
- Data providers for parameterized tests
- Edge cases with negative and decimal numbers

### UserRegistrationTest.php
- Email validation
- Password strength validation
- Username validation with data providers

## 🔄 CI/CD Integration

The project includes a GitHub Actions workflow (`.github/workflows/testomatio.yml`) that:

1. Sets up PHP environment
2. Installs Composer dependencies
3. Runs PHPUnit tests
4. Generates JUnit XML report
5. Uploads results to Testomat.io

To use it, add these secrets to your GitHub repository:
- `TESTOMATIO` - Your Testomat.io API key
- `TESTOMATIO_URL` - Your Testomat.io instance URL (optional)

## 📖 Test Annotations

Tests can be annotated with Testomat.io IDs in docblocks:

```php
/**
* Test description
* @testomatio @T123abc
*/
public function testExample(): void
{
// test code
}
```

## 🧪 Project Structure

```
phpunit/
├── src/
│ └── Calculator.php # Example class to test
├── tests/
│ ├── CalculatorTest.php # Unit tests
│ └── UserRegistrationTest.php # Feature tests
├── build/
│ └── logs/
│ └── junit.xml # Generated test report
├── composer.json # PHP dependencies
├── phpunit.xml # PHPUnit configuration
└── README.md # This file
```

## 📚 Learn More

- [PHPUnit Documentation](https://docs.phpunit.de/)
- [Testomat.io Documentation](https://docs.testomat.io/)
- [JUnit XML Format](https://llg.cubic.org/docs/junit/)
26 changes: 26 additions & 0 deletions phpunit/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "testomatio/phpunit-example",
"description": "PHPUnit example project with Testomat.io integration",
"type": "project",
"license": "MIT",
"require": {
"php": "^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0",
"testomatio/reporter": "^1.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"config": {
"sort-packages": true
}
}
23 changes: 23 additions & 0 deletions phpunit/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="PHPUnit Example Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="Testomatio\Reporter\PHPUnit" file="vendor/testomatio/reporter/src/PHPUnit.php" />
</listeners>
<coverage>
<include>
<directory>src</directory>
</include>
</coverage>
<logging>
<junit outputFile="report/junit.xml"/>
</logging>
</phpunit>
33 changes: 33 additions & 0 deletions phpunit/report/junit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="" tests="22" assertions="23" errors="0" warnings="0" failures="0" skipped="0" time="0.015253">
<testsuite name="PHPUnit Example Test Suite" tests="22" assertions="23" errors="0" warnings="0" failures="0" skipped="0" time="0.015253">
<testsuite name="App\Tests\CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" tests="12" assertions="13" errors="0" warnings="0" failures="0" skipped="0" time="0.008569">
<testcase name="testAddition" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="21" assertions="1" time="0.004411"/>
<testcase name="testAdditionWithNegativeNumbers" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="31" assertions="1" time="0.000530"/>
<testcase name="testSubtraction" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="41" assertions="1" time="0.000686"/>
<testcase name="testMultiplication" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="51" assertions="1" time="0.000105"/>
<testcase name="testDivision" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="61" assertions="1" time="0.000501"/>
<testcase name="testDivisionByZeroThrowsException" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="71" assertions="2" time="0.000752"/>
<testcase name="testAdditionWithPositiveNumbers" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="82" assertions="1" time="0.000127"/>
<testcase name="testAdditionWithNegatives" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="92" assertions="1" time="0.000121"/>
<testcase name="testAdditionWithMixedNumbers" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="102" assertions="1" time="0.000162"/>
<testcase name="testAdditionWithDecimals" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="112" assertions="1" time="0.000175"/>
<testcase name="testAdditionWithZero" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="122" assertions="1" time="0.000513"/>
<testcase name="testPercentage" class="App\Tests\CalculatorTest" classname="App.Tests.CalculatorTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/CalculatorTest.php" line="132" assertions="1" time="0.000486"/>
</testsuite>
<testsuite name="App\Tests\UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" tests="10" assertions="10" errors="0" warnings="0" failures="0" skipped="0" time="0.006684">
<testcase name="testValidEmailFormat" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="17" assertions="1" time="0.002312"/>
<testcase name="testInvalidEmailFormat" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="27" assertions="1" time="0.001022"/>
<testcase name="testStrongPassword" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="37" assertions="1" time="0.000515"/>
<testcase name="testWeakPassword" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="47" assertions="1" time="0.000320"/>
<testcase name="testUsernameValidationWithValidUsername" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="57" assertions="1" time="0.000522"/>
<testcase name="testUsernameValidationWithAlphanumeric" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="67" assertions="1" time="0.000214"/>
<testcase name="testUsernameValidationTooShort" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="77" assertions="1" time="0.000469"/>
<testcase name="testUsernameValidationWithSpaces" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="87" assertions="1" time="0.000552"/>
<testcase name="testUsernameValidationWithSpecialChars" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="97" assertions="1" time="0.000407"/>
<testcase name="testUsernameValidationEmpty" class="App\Tests\UserRegistrationTest" classname="App.Tests.UserRegistrationTest" file="/Users/o.pelykh/projects/testomat.io/examples/phpunit/tests/UserRegistrationTest.php" line="107" assertions="1" time="0.000351"/>
</testsuite>
</testsuite>
</testsuite>
</testsuites>
Loading