在本系列的最后一部分,是时候设置端到端 / 集成测试环境,并确保咱们已经准备好检查咱们工做的质量。php
在本系列的前几部分中,咱们创建了一个构建工具,一些静态代码分析器,并开始编写单元测试。html
为了使咱们的测试堆栈更完整,有一些测试能够检查你的代码是否在真实环境中运行,以及它是否能在更复杂的业务场景中运行良好。laravel
在这里,咱们能够使用为行为驱动开发构建的工具——官方 PHP 的 Cucumber 实现——Behat。咱们能够经过运行如下代码来安装它:git
$ php composer.phar require --dev behat/behat
增长一个目标到 build.xml(在本文的第一部分中描述了 Phing 设置)web
<target name="behat"> <exec executable="bin/behat" passthru="true" checkreturn="true"/></target>…<target name="run" depends="phpcs,phpcpd,phan,phpspec,behat"/>
而后,你应该为文件 features/price.feature 的测试建立一个规范。sql
Feature: Price Comparison In order to compare prices As a customer I need to break the currency barrier Scenario: Compare EUR and PLN Given I use nbp.pl comparator When I compare “100EUR” and “100PLN” Then It should r
eturn some result
这个测试场景很是容易阅读,而且应该给你一个关于该特性应该如何工做的良好印象。不幸的是,计算机一般并不真正理解人类语言,因此如今是为每一步编写代码的时候了。shell
你能够经过运行 ./bin/behat-init 来生成它的代码模板。它应该会建立一个这样的类:bootstrap
1 //features/bootstrap/FeatureContext.php use Behat\Behat\Context\SnippetAcceptingContext;use Behat\Gherkin\Node\PyStringNode;use Behat\Gherkin\Node\TableNode;class FeatureContext implements SnippetAcceptingContext{ /** * Initializes context. */ public function __construct() { }}
而后你能够执行:服务器
1 $ bin/behat --dry-run --append-snippets
Behat 将自动为场景中定义的每一个步骤建立函数。
如今你能够经过填充函数的主体来开始实现真正的检查:架构
// features/bootstrap/FeatureContext.php <?phpuse Behat\Behat\Context\Context;use Domain\Price;use Domain\PriceComparator;use Infrastructure\NBPPriceConverter; /*** Defines application features from the specific context.*/class FeatureContext implements Context{ /** @var PriceComparator */ private $priceComparator; /** @var int */ private $result; /** * Initializes context. * * Every scenario gets its own context instance. * You can also pass arbitrary arguments to the * context constructor through behat.yml. */ public function __construct() { } /** * @Given I use nbp.pl comparator */ public function iUseNbpPlComparator() { $this->priceComparator = new PriceComparator(new NBPPriceConverter()); } /** * @When I compare :price1 and :price2 */ public function iCompareAnd($price1, $price2) { preg_match('/(\d+)([A-Z]+)/', $price1, $match1); preg_match('/(\d+)([A-Z]+)/', $price2, $match2); $price1 = new Price($match1[1], $match1[2]); $price2 = new Price($match2[1], $match2[2]); $this->result = $this->priceComparator->compare($price1, $price2); } /** * @Then It should return some result */ public function itShouldReturnSomeResult() { if (!is_int($this->result)) { throw new \DomainException('Returned value is not integer'); } }}
最后,使用 ./bin/phing 运行全部的测试。你应该获得如下结果:
Buildfile: /home/maciej/workspace/php-testing/build.xmlMyProject > phpcs: MyProject > phpcpd: phpcpd 4.0.0 by Sebastian Bergmann.0.00% duplicated lines out of 103 total lines of code. Time: 17 ms, Memory: 4.00MB MyProject > phan: MyProject > phpspec: / skipped: 0% / pending: 0% / passed: 100% / failed: 0% / broken: 0% / 3 examples2 specs3 examples (3 passed)15ms MyProject > behat: Feature: Price Comparison In order to compare prices As a customer I need to break the currency barrier Scenario: Compare EUR and PLN # features/price.feature:6 Given I use nbp.pl comparator # FeatureContext::iUseNbpPlComparator() When I compare "100EUR" and "100PLN" # FeatureContext::iCompareAnd() Then It should return some result # FeatureContext::itShouldReturnSomeResult()1 scenario (1 passed)3 steps (3 passed)0m0.01s (9.13Mb) MyProject > run: BUILD FINISHED Total time: 1.1000 second
正如你所看到的,Behat 准备了一份很好的报告,说明咱们的应用程序作了什么,结果是什么。下一次,当项目经理询问你在测试中涉及到哪些场景时,你能够给他一个 Behat 输出!
每一个测试都包括:
每一个部分均可以包含多个与“And”关键字链接的步骤:
Scenario: Compare EUR and PLN Given nbp.pl comparator is available And I use nbp.pl comparator When I compare "100EUR" and "100PLN" And I save the result Then It should return some result And the first amount should be greater
Behat 容许你为你的测试定义多个上下文。这意味着你能够将步骤代码分割成多个类,并从不一样的角度去测试你的场景。
你能够例如:为 web 上下文编写代码,它将使用你的应用程序 HTTP 控制器运行你的测试步骤。你还能够建立“domain”上下文,它将只使用 PHP API 调用来运行你的业务逻辑。经过这种方式,你能够单独地测试业务逻辑集成,从端到端应用程序测试。
关于如何在 Behat 创建许多上下文的更多信息,请参考 http://behat.org/en/latest/userguide/context.html 的文档。
正如一开始所提到的,你能够使用 Behat 进行集成测试。一般状况下,你的代码依赖于一些外部的第三方系统。当咱们在第 2 部分中编写单元测试时,咱们老是假设外部依赖关系像预期的那样工做。使用 Behat,你能够编写测试场景,它将自动运行你的代码,并检查它是否正确地使用真实场景的服务。
最重要的是,Behat 对于测试系统使用的复杂的端到端场景很是有用。它容许你隐藏在一个可读性的名字后面运行测试步骤所需的复杂代码,并编写一我的人都能理解的场景。
从以上的文章中,你已经学习了如何在你的项目中设置六个有用的工具:
如今,你能够向 git 提交钩子添加 ./bin/phing,并设置持续集成来运行每一个提交的测试。
是否是忽然之间,没有什么能阻止你写出高质量的 PHP 代码!
Well done!
不少PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提高,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货须要的能够免费分享给你们,须要的加群(点击→)677079770
推荐阅读: