When we talk about automated testing, we usually refer to automatic tests instead of manual tests, right? But what if we could automate the automation? I mean automatically running tests whenever something is pushed to the repository or under certain conditions.
GitHub has a feature called GitHub actions, and the action is called Laravel
.
This is the core of CI/CD (continuous integration and continuous delivery/deployment).
A typical example is if someone pushes the code to a branch, a GitHub action is launched to run the test automatically.
If the test fails, there will be an error with an "x" icon. The developer will then know what to fix without anyone looking at the code or testing it manually.
So, how does it work? Let's take a look at a practical demonstration.
GitHub Actions in Action
It's straightforward to set up. You don't need any external CI tool or pay for anything. You just need GitHub Actions.
This is a GitHub feature for running anything. It is not specific to testing or Laravel, but we will use it to run tests.
In your repository, click on Actions
.
You will be taken to a page where you can select a workflow. Since this is a Laravel repository, GitHub suggests the Laravel
action.
After clicking Configure
, a file laravel.yml
will be created in the .github/workflows
folder.
The file that is automatically generated instructs GitHub to run many things.
- First, it uses the ready-made
shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e
action to set up PHP. By default, it sets PHP to 8.0. Laravel 11 requires PHP 8.2, so we must set the PHP version to at least 8.2 for the action. - Then, it uses another pre-defined action
actions/checkout@v4
, which sets up the Laravel application by installingcomposer
packages, generating a key, adding directory permissions, creating a database (by default SQLite), and executing the tests.
You can call this thing a "scenario". After setting the PHP version, you can commit the changes. The modified action looks like this:
name: Laravel on: push: branches: [ "main" ] pull_request: branches: [ "main" ] jobs: laravel-tests: runs-on: ubuntu-latest steps: - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e with: php-version: '8.2' - uses: actions/checkout@v4 - name: Copy .env run: php -r "file_exists('.env') || copy('.env.example', '.env');" - name: Install Dependencies run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist - name: Generate key run: php artisan key:generate - name: Directory Permissions run: chmod -R 777 storage bootstrap/cache - name: Create Database run: | mkdir -p database touch database/database.sqlite - name: Execute tests (Unit and Feature tests) via PHPUnit/Pest env: DB_CONNECTION: sqlite DB_DATABASE: database/database.sqlite run: php artisan test
Now, an icon appears on the repository near the commit message. This means that the action workflow is being queued.
After the workflow is finished, you will see a green tick icon in case of success.
You can see a complete workflow after clicking the icon and going to the details.
Also, you can see how the workflow is being executed here.
Next, you see a red "x" icon if the test fails.
In the details, you can see the failed test message, which is the same as if you were running the test locally. In this case, I installed Laravel Breeze, which is why I get a Vite manifest not found at
error.
There are at least two ways to fix the tests now. The easiest is to set withoutVite()
in the setup of tests.
tests/TestCase.php:
use Illuminate\Foundation\Testing\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase{ use CreatesApplication; protected function setUp(): void { parent::setUp(); $this->withoutVite(); } }
The test is run automatically after committing to and pushing the change because of the workflow condition.
name: Laravel on: push: branches: [ "main" ] pull_request: branches: [ "main" ] // ...
This time, the tests have run successfully.
This is how automated tests are automated, without anyone even launching the php artisan test
locally or somewhere else to ensure the quality of the code being pushed and deployed.
You can do a lot more with GitHub actions, like run Laravel Pint to format code.
Notice: this demonstration is very simplified. In most cases, you shouldn't directly push to the main
branch. For example, you should use the develop
branch and open a Pull Request, which would trigger the GitHub Action. Then, merge to the main
only when ready to deploy.
No comments or questions yet...