While working on the Easy Breadcrumb module for Drupal, I came across a situation where a test was failling on Gitlab but was passing with DDev: https://www.drupal.org/project/easy_breadcrumb/issues/3615550
The difference that mattered was that Gitlab serves the site from http://localhost/web for testing and locally it gets served from a fully qualified domain name, ie. http://ddev.site.example.com.
Getting the test to fail locally
Using firecow/gitlab-ci-local
To get the test to fail locally, I used the suggestions at https://project.pages.drupalcode.org/gitlab_templates/info/test-locally/ , which suggested firecow/gitlab-ci-local . I did get that working but I ran into a hitch. My work computer is a Mac with an ARM64 chip and gitlab-ci-local tries to install selenium/standalone-chrome:127.0, which doesn't support ARM64. I dug around and figured out that I could use selenium/standalone-chromium:latest instead by adding a few lines in .gitlab-ci.yml:
phpunit:
services:
- !reference [.with-database]
- name: selenium/standalone-chromium:latest
alias: selenium
# The lines below are to filter which tests run. In this case, only tests in the
# "redirect" group.
variables:
_PHPUNIT_TESTGROUPS: "redirect"Then, on the command line, to just run PHPUnit and not most of the other steps, I used the --stage flag to just run jobs in the test stage, which by default is just PHPUnit:
$ drupal-ci-local --stage=testThat worked and I was able to reproduce locally. But, it took about a minute to run the test instead of 2 or 3 seconds with DDev.
Using DDEV to serve a Drupal site from a subdirectory instead of a subdomain
This way is not perfect, but it worked well enough for me to use Xdebug when running tests and when browing the site in a browser.
The code below results in the site being served from a subdirectory named easy, ie. http://example.com/easy.
First, cd to root of project, then:
mkdir router
ls -s ./web ./router/easyThen, in .ddev/config.yaml
docroot: routerNext, in settings.php
if (isset($GLOBALS['request'])) {
$request = $GLOBALS['request'];
$script_name = $request->server->get('SCRIPT_NAME');
if ($script_name === '/easy/index.php' || $script_name === '/index.php') {
$request->server->set('SCRIPT_NAME', '/easy/index.php');
}
}Then, in .ddev/nginx_full/nginx-site.conf, replace the section that starts with 'location /' to be like this instead:
# 1. CSS/JS caches
location ~* ^/easy/sites/.*/files/(css|js)/ {
try_files $uri @rewrite;
expires max;
log_not_found off;
}
# 2. Image styles
location ~* ^/easy/sites/.*/files/styles/ {
try_files $uri @rewrite;
}
# 3. Clean URLs
location /easy {
try_files $uri $uri/ /easy/index.php?$query_string;
}
# 4. Fallback
location @rewrite {
rewrite ^/easy/(.*)$ /easy/index.php?$query_string;
}To run phpunit tests, pass in SIMPLETEST_BASE_URL.
Example which just runs ones test:
ddev exec SIMPLETEST_BASE_URL=http://localhost/easy vendor/bin/phpunit --bootstrap web/core/tests/bootstrap.php --filter testEasyBreadcrumbFollowRedirects web/modules/custom/easy_breadcrumb