运行并通过所有 Symfony 应用程序测试

在上一章中,我们开始尝试遵循 SOLID 原则编写解决方案代码。要开发应用程序的其他部分,我们可以继续遵循相同的流程。在本章中,我冒昧地完成了所有其他测试以及通过这些测试所需的解决方案代码。我们将通过这些测试并确保它们通过。

设置本地环境

在本地开发机器上查看 技术要求 部分提供的源代码,并在主机上运行以下命令配置开发环境:

$ cd docker
$ docker-compose build && docker-compose up -d

运行这些命令后,通过运行以下命令确保我们在本书前面构建的容器已启动并正在运行:

$ docker ps

您应该看到以下 Docker 容器名称:

docker_server-web_1
docker_app-phpmyadmin_1
docker_server-mysql_1

现在容器已经运行,我们需要为运行在 docker_server-web_1 容器中的 Symfony 和 Behat 应用程序做好准备,安装它们所依赖的软件包,并创建 PHP 应用程序所需的数据库和表格。

准备 Symfony 应用程序和测试

现在,让我们设置 Symfony 应用程序所需的数据库表和库。仍在 docker 目录内时,从主机运行以下命令:

$ docker exec -i docker_server-web_1 /var/www/html/symfony/setup.sh

或者,在 docker_server-web_1 容器内运行以下命令:

/var/www/html/symfony# ./setup.sh

setup.sh 文件只是我添加的一个 shell 脚本,用于轻松配置我们的 Symfony 应用程序,并准备好运行测试所需的数据库和表格。

打开下面的 shell 文件,你会发现我们只是运行了一些 Doctrine 命令,并使用 Composer 安装了所需的所有 Symfony 依赖项:

codebase/symfony/setup.sh
#!/bin/bash
composer install -d /var/www/html/symfony/
# Test DB
php /var/www/html/symfony/bin/console doctrine:database:create -n --env=test
php /var/www/html/symfony/bin/console doctrine:migrations:migrate -n --env=test
php /var/www/html/symfony/bin/console doctrine:fixtures:load -n --env=test
# Main DB
php /var/www/html/symfony/bin/console doctrine:database:create -n
php /var/www/html/symfony/bin/console doctrine:migrations:migrate -n
php /var/www/html/symfony/bin/console doctrine:fixtures:load -n

当我们在持续集成(CI)机器上运行应用程序时,这个 shell 脚本就会派上用场。

运行 setup.sh 命令后,你的开发环境就可以在 Symfony 应用程序中运行所有单元测试和集成测试了。

第 5 章 "单元测试" 中,我们创建了一个 shell 脚本,名为 codebase/symfony/runCoverage.sh。该 shell 脚本将帮助我们运行所有测试,并检查解决方案代码的测试覆盖率。但实际上,我们不必覆盖应用程序中的所有代码,因为其中有些是没有测试的第三方库,有些可能只是普通的旧 PHP 对象(POPO)类。但对于我们开发的代码,我们应该为它们添加自动化测试。

如果你认为需要从代码覆盖率报告中排除一些类,可以打开 codebase/symfony/phpunit.xml 配置文件,添加你想从覆盖率报告中排除的目录。

docker_server-web_1 容器中,打开 Symfony 应用程序内的 codebase/symfony/tests 目录,你会看到以下测试:

image 2023 10 24 15 23 33 946
Figure 1. Figure 9.1 – Symfony tests directory

我们有三个主要的测试目录:FunctionalIntegrationUnit。本示例中的功能测试是控制器测试,也就是使用 HTTP 请求的测试;你也可以把它们看作集成测试,但它们涵盖了更多的集成代码。集成测试是对不同的自定义类以及它们之间如何交互进行的测试,确保它们都能按预期运行。最后,单元测试是简单的测试,主要针对特定类中的单个单元或函数。

你可以浏览 codebase/symfony/src 中的目录和类,查看测试所针对的实际类。

让我们看看测试是否通过;在主机上运行以下命令:

$ docker exec -i docker_server-web_1 /var/www/html/symfony/runTests.sh

或者,在 docker_server-web_1 容器内运行以下命令:

/var/www/html/symfony# ./runTests.sh

由于我们已经配置了测试所需的数据库和表,您应该看到以下结果:

image 2023 10 24 15 27 13 108
Figure 2. Figure 9.2 – Passing Symfony tests

看起来我们有很多通过的测试,但让我们打开其中一个测试类,看看我们到底在测试什么。

打开 codebase/symfony/tests/Integration/DAL/Reader/ColorReaderTest.php; 你会看到以下内容:

<?php
namespace App\Tests\Integration\DAL\Reader;

use App\DAL\Reader\Doctrine\ColorReader;
use App\Entity\Color;
use App\Model\ToyColor;

class ColorReaderTest extends DataReaderTestBase
{
    public function testCanReadColors()
    {
        $reader = $this->getServiceContainer()->get(ColorReader::class);
        $colorsFromDb = $reader->getAll();

        /** @var Color $color */
        foreach ($colorsFromDb as $color) {
            $this->assertInstanceOf(ToyColor::class, $color);
            $this->assertIsInt($color->getId());
            $this->assertNotNull($color->getName());
        }
    }
}

你会注意到,在这个测试类中,我们从数据库中读取数据,并针对数据库中的结果运行一些断言。在 第 7 章 "使用 BDD 和 TDD 构建解决方案代码" 中,我们创建了测试所需的数据库和实际解决方案代码所需的主数据库。

我们在 docker_server-mysql_1 容器中创建了以下数据库:

image 2023 10 24 15 34 31 852
Figure 3. Figure 9.3 – MySQL databases

我们将 cars 数据库用于实际解决方案代码,将 cars_test 用于自动测试。这样,我们的自动化测试就不会污染主应用程序数据库。

最后,在部署到 CI 解决方案之前,让我们运行之前创建的 runCoverage.sh shell 脚本。

在主机上运行以下命令:

$ docker exec -i docker_server-web_1 /var/www/html/symfony/runCoverage.sh

或者,在 docker_server-web_1 容器内运行以下命令:

/var/www/html/symfony# ./runCoverage.sh

现在,您应该看到以下测试结果:

image 2023 10 24 15 37 11 498
Figure 4. Figure 9.4 – Test coverage report

伟大的!在此阶段,我们确定测试运行正常并且它们也可以连接到测试数据库:

image 2023 10 24 15 37 45 518
Figure 5. Figure 9.5 – Test data

如果您检查 cars_test MySQL 数据库中的 toy_cars 表,您应该会看到自动化测试创建的一些示例数据。

接下来,让我们继续进行 Behat 应用程序中定义的更复杂的功能测试。

准备 Behat 应用程序和测试

在上一节中,我们运行并通过了 Symfony 应用程序的所有测试。现在,我们需要确保 Behat 应用程序中的行为驱动测试也已通过。

在主机上运行以下命令,设置 Behat 应用程序:

$ docker exec -i docker_server-web_1 /var/www/html/behat/setup.sh

或者,在 docker_server-web_1 容器内运行以下命令:

/var/www/html/behat# ./setup.sh

就像之前在 Symfony 应用程序中所做的那样,我们首先需要设置 Behat 应用程序并安装其依赖项。

第 6 章 "应用行为驱动开发" 中,我们使用 Gherkin 语言创建了测试功能和场景。我们还创建了一些 Context PHP 类,其中包含我们在创建的功能文件中定义的步骤。Behat 将执行这些 Context 类作为 PHP 功能测试。

Symfony 测试与 Behat 应用程序测试之间的区别在于,Behat 测试并不关心我们如何实现结果,也不关心特定 PHP 类如何与其他 PHP 类交互。它们只关心测试非常高级的功能和行为场景。

就是这样—​现在,我们已经准备好运行我们的行为驱动测试了。

从主机运行以下命令,看看是否可以通过我们的 Behat 测试:

docker exec -i docker_server-web_1 /var/www/html/behat/runBehatTests.sh

或者,在 docker_server-web_1 容器内运行以下命令:

/var/www/html/behat# ./runBehatTests.sh

您应该看到以下结果:

image 2023 10 24 16 11 04 323
Figure 6. Figure 9.6 – Behat tests passing

太好了!我们已经通过了定义的所有测试场景。如果您想查看所有功能文件和场景,可以在 codebase/behat/features 中打开这些文件。

现在,我们已经确定我们的自动化测试能在开发机器上正常工作,我们可以在 Bitbucket Pipelines 中将它们用于我们的 CI 解决方案了。