Actions & tests
A lot of what you do in a project is the same handful of commands: install dependencies, run migrations, clear a cache, run the tests. Envoryx has two sections for exactly that, so you don’t have to open a terminal every time.
Actions
Section titled “Actions”The Actions section runs predefined commands in the matching runtime container, as the project owner, and shows you the output live. The list is fixed on purpose: your browser only sends the id of an action, never a command line, so nothing can be smuggled in. The list holds the actions of every runtime the project has, but only those whose files are there can be clicked: composer install needs a composer.json, rails db:migrate a bin/rails, and so on. The others stay greyed out with the reason next to them, so a Symfony project shows the Artisan actions with artisan not found in project. pnpm and Yarn need their lock file, except in a project whose Node.js runtime is set to that package manager: there package.json is enough, so a fresh project can run its first install. Anything destructive asks before it runs.


This is what’s available:
| Group | Actions |
|---|---|
| PHP | php -v, php -m |
| Composer | composer install, composer update, composer dump-autoload |
| Artisan (Laravel) | migrate, migrate:fresh --seed, db:seed, key:generate, storage:link, cache:clear, optimize:clear |
| Symfony | console cache:clear, console doctrine:migrations:migrate |
| CMS | drush site:install, drush cache:rebuild (Drupal), typo3 setup, Shopware system:install --basic-setup, craft install |
| Node.js | node -v; npm install, ci, run build; pnpm install, run build; yarn install, build |
| Python | python --version, python -m venv .venv; pip install -r requirements.txt, freeze; uv sync, lock |
| Django | manage.py migrate, makemigrations, collectstatic, check, flush |
| Go | go version, go build ./..., go vet ./..., gofmt -l ., go mod tidy, go mod download, go generate ./... |
| Ruby | ruby --version, rubocop; Bundler install, update, outdated |
| Rails | db:prepare, db:migrate, db:rollback, db:seed, routes, assets:precompile, tmp:clear, about |
| Java | java -version; Maven package, clean, dependency:tree, versions:display-dependency-updates; Gradle build, clean, dependencies, tasks |
| .NET | dotnet --info, restore, build, clean, format, list package --outdated; dotnet ef database update, dotnet ef migrations list |
The CMS installers for Drupal, TYPO3, Shopware and Craft set the site up against the project database. Drupal, TYPO3 and Craft print the generated admin password at the end, so keep an eye on the output. Shopware’s installer always creates the login admin with the password shopware, which you’d better change in the admin afterwards. WordPress has no action here; its installer runs in the browser when you open the site.
You can run the same actions from a script or let an assistant do it:
envoryx project run shop # list the actions of the projectenvoryx project run shop artisan:migrate # run one, with live outputIf what you need isn’t in the list, the terminal or envoryx project exec is the way to go.
The Tests section looks through the project directory for test suites and runs them in the runtime container, again with live output. It recognises these:


| Suite | Found by | Filter |
|---|---|---|
| Pest | vendor/bin/pest (PHPUnit isn’t listed then, Pest runs those tests too) |
--filter |
| PHPUnit | vendor/bin/phpunit or bin/phpunit (Symfony’s bridge), when there’s no Pest |
--filter |
| npm scripts | test and test:* in package.json (yarn or pnpm when their lock file is there) |
passed on to the script |
| Playwright | playwright.config.* |
--grep |
| Cypress | cypress.config.* |
--spec |
| pytest | pytest.ini, conftest.py, pytest in pyproject.toml ([tool.pytest], the dependencies, uv’s [dependency-groups]), in uv.lock or in the requirements |
-k |
| Django | manage.py |
test label |
| Go | go.mod - go test ./... through gotestsum |
-run |
| RSpec | a spec/ directory and rspec in Gemfile.lock |
-e (example name) |
| Rails | bin/rails and a test/ directory - bin/rails test |
-n (test name or /regexp/) |
| Maven, Gradle | pom.xml - mvn test, build.gradle - gradle test |
-Dtest, --tests |
| .NET | a test project (xUnit, NUnit, MSTest, TUnit or the test SDK) - dotnet test |
--filter |
If composer.json asks for a test suite that isn’t installed yet, it still shows up, with a hint to run composer install first. Whatever you type as a filter goes to the runner as a single argument, never through a shell.
When a run finishes, you want to know what broke. PHPUnit, Pest, Playwright, Cypress, pytest, Go, RSpec, Maven and Gradle write a JUnit report (RSpec needs rspec_junit_formatter in the bundle for that), dotnet test a TRX report, and Envoryx shows the counts plus every failed test with its message, and with its file and line where the runner names them. Go names only the file, not its package directory. Maven and Gradle reports carry the message but no file or line, so for those you look at the details or the output. rails test, RSpec without the formatter, Django’s manage.py test and Vitest or Jest behind a package.json test script write no report, but Envoryx reads their summary and failures from the output and shows them the same way. Only for other scripts does the exit code alone decide whether it passed. The last 50 runs stay under Recent runs, each with its output, so you can still read what an older run printed. Cancelling a run or closing the tab stops it.


Tests get their own database
Section titled “Tests get their own database”A test suite that resets the schema or loads fixtures does that to whatever database it’s pointed
at, and the variables Envoryx injects point at your development database. Laravel’s
RefreshDatabase would happily run migrate:fresh on your data. That’s why the runners that work
with a database go to <database>_test on the project’s database server instead.
For PHPUnit and Pest, Envoryx points DB_DATABASE, DB_URL and DATABASE_URL there. The other
<env> entries of phpunit.xml (or phpunit.xml.dist when there’s no phpunit.xml) are handed to
the run as they are. PHPUnit itself only sets what the environment doesn’t have yet, and in the
container everything is already set, your own QUEUE_CONNECTION=redis as well as the MAIL_*
variables for Mailpit. Without that, a test that dispatches a job would put it on your development
queue, the dev worker would write into your development database, and its mail would land in your
Mailpit inbox. The database entries are the exception: they only count when the tests run on SQLite
(DB_CONNECTION=sqlite in phpunit.xml). Symfony’s
Doctrine recipe appends _test on its own (dbname_suffix under when@test in
config/packages/doctrine.yaml); when that line is there, DATABASE_URL stays as it is, so both
roads end at the same database. RSpec and rails test run in the test environment, because Active
Record merges DATABASE_URL into every environment. The Java and .NET runs rewrite their database
URLs and connection string the same way, see the Java and
.NET pages. Django’s runner and pytest-django (pytest next to a
manage.py) name their test database test_<database> themselves.
In every case Envoryx creates the test database before the run, as the administrator, because the
MySQL and MariaDB project login isn’t allowed to create databases. What goes into it is up to the
tests: Laravel’s RefreshDatabase migrates on its own, Rails loads its schema, and for Symfony you
run bin/console doctrine:schema:create --env=test once. A project on SQLite keeps its file, and
MongoDB, npm scripts, Playwright, Cypress, plain pytest and go test run with the project’s
variables as they are.
Playwright and Cypress need browsers and system libraries that the Node image doesn’t include. Browser tests are usually better off on a machine or CI runner that has them.