专栏名称: HULK一线技术杂谈
HULK是360的私有云平台,丰富的一线实战经验,为你带来最有料的技术分享
目录
相关文章推荐
钱江晚报  ·  消息传来!英雄白龙,不幸去世 ·  昨天  
钱江晚报  ·  《甄嬛传》女演员自曝!网友怒了 ·  2 天前  
钱江晚报  ·  大S妈妈首度发文,回应女儿去世 ·  2 天前  
杭州交通918  ·  大涨!还在涨!创历史新高🤯 ·  2 天前  
钱江晚报  ·  岳云鹏,传来喜讯! ·  3 天前  
51好读  ›  专栏  ›  HULK一线技术杂谈

如何提高PHP代码的质量?第三部分 端到端\/集成测试

HULK一线技术杂谈  · 公众号  ·  · 2018-06-27 18:00

正文

女主宣言

说实话,在代码质量方面,PHP的压力非常大。通过阅读本系列文章,您将了解如何提高PHP代码的质量。

PS:丰富的一线技术、多元化的表现形式,尽在“ HULK一线技术杂谈 ”,点关注哦!

在本系列的最后一部分,是时候设置端到端/集成测试环境,并确保我们已经准备好检查我们工作的质量。

在本系列的前几部分中,我们建立了一个构建工具,一些静态代码分析器,并开始编写单元测试。如果你还没有读过这些,那就去看看吧!


如何提高PHP代码的质量?第一部分 自动化工具

如何提高PHP代码的质量?第二部分 单元测试

为了使我们的测试堆栈更完整,有一些测试可以检查你的代码是否在真实环境中运行,以及它是否能在更复杂的业务场景中运行良好。

在这里,我们可以使用为行为驱动开发构建的工具——官方PHP的 Cucumber 实现——Behat。我们可以通过运行以下代码来安装它:

$ php composer.phar require --dev behat/behat

增加一个目标到 build.xml(在本文的第一部分中描述了Phing设置)

<target name="behat">
   <exec executable="bin/behat" passthru="true" checkreturn="true"/>target>

<target name="run" depends="phpcs,phpcpd,phan,phpspec,behat"/>

然后,你应该为文件 features/price.feature 的测试创建一个规范。

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” and100PLN”
   Then It should return some result

这个测试场景非常容易阅读,并且应该给你一个关于该特性应该如何工作的良好印象。不幸的是,计算机通常并不真正理解人类语言,所以现在是为每一步编写代码的时候了。

你可以通过运行 ./bin/behat-init 来生成它的代码模板。它应该会创建一个这样的类:

//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 ()    {    } }

然后你可以执行:

$ bin/behat --dry-run --append-snippets
Behat将自动为场景中定义的每个步骤创建函数。
现在你可以通过填充函数的主体来开始实现真正的检查:
// features/bootstrap/FeatureContext.php

use 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输出!

1

测试的结构

每个测试都包括:

  • 对该场景的一些准备,用“Given”部分表示

  • “When”部分所涵盖的一些动作

  • 一些检查被标记为“Then”部分

每个部分都可以包含多个与“And”关键字连接的步骤:

Scenario: Compare EUR and PLN
    Given nbp.pl comparator is available
    And I 






请到「今天看啥」查看全文