tdd和ddd
This article was peer reviewed by Christopher Pitt and Thomas Punt. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!
本文由克里斯托弗·皮特 ( Christopher Pitt)和托马斯·蓬特 ( Thomas Punt)进行了同行评审。 感谢所有SitePoint的同行评审人员使SitePoint内容达到最佳状态!
Sylius is an e-commerce application / framework based on Symfony. It boasts 100% code coverage, which is impressive for a PHP application of that size. In this article, we are going to walk through the different kinds of tests available and try out some Test and Behavior Driven Development (TDD/BDD). See the Sylius installation guide page for instructions, as this article assumes you have a working installation with example data and you can run Behat, PHPUnit and phpspec tests.
Sylius是基于Symfony的电子商务应用程序/框架。 它拥有100%的代码覆盖率 ,对于该大小PHP应用程序而言,这是令人印象深刻的。 在本文中,我们将逐步介绍可用的各种测试,并尝试一些测试和行为驱动的开发(TDD / BDD)。 见Sylius安装指南的说明,如本文假定您有带有示例数据的工作安装,你可以运行贝哈特 , PHPUnit的和phpspec测试。
In the web root, there’s a src
folder which holds all Sylius-related code. This allows you to make use of the app
folder for your application development without unnecessarily treading on Sylius’ toes. As we are interested in test-driven development (first, write tests that fail before writing the code) let’s dive in, the Sylius way.
在网络根目录中,有一个src
文件夹,其中包含所有与Sylius相关的代码。 这使您可以在app
程序开发中使用app
文件夹,而不必踩踏Sylius的脚趾。 由于我们对测试驱动的开发感兴趣(首先,在编写代码之前编写失败的测试),所以让我们深入了解Sylius。
We start by setting up our test database.
我们首先建立测试数据库。
php bin/console doctrine:database:create --env=test
php bin/console doctrine:schema:create --env=test
Sylius测试的类型 (Types of Sylius Tests)
Some of the basics of the tools below have already been covered in this post, but we’ll recap them here on Sylius examples to keep with the theme.
这篇文章已经介绍了下面这些工具的一些基础知识,但是为了与主题保持一致,我们将在Sylius示例中对它们进行重述。
PHPUnit (PHPUnit)
Sylius comes with a lot of PHPUnit functional tests. The configuration file, phpunit.xml.dist
, is in the web root and the unit tests are in the tests
folder. From the root of our application, let’s run tests in tests/Controller/CountryApiTest.php
:
Sylius附带了许多PHPUnit功能测试。 配置文件phpunit.xml.dist
位于Web根目录中,而单元测试位于tests
文件夹中。 从应用程序的根目录开始,让我们在tests/Controller/CountryApiTest.php
运行测试:
./vendor/phpunit/phpunit/phpunit -c ./phpunit.xml.dist tests/Controller/CountryApiTest
The command is made up of 3 parts – path to PHPUnit, our configuration file and the unit test class. Open tests/Controller/CountryApiTest.php
and take a look at the class. It extends JsonApiTestCase which we can trace back to ApiTestCase and WebTestCase, part of the Symfony framework package.
该命令由三部分组成-PHPUnit的路径,我们的配置文件和单元测试类。 打开tests/Controller/CountryApiTest.php
并查看该类。 它扩展了JsonApiTestCase,我们可以追溯到Symfony框架包的一部分ApiTestCase和WebTestCase。
规格书 (Phpspec)
Behavior Driven Development (BDD) emerged from Test Driven Development (TDD), focusing attention on how a user interacts with an application and how the application behaves. SpecBDD is the part of BDD which considers how the smaller bits of an application work together to make things happen.
行为驱动开发(BDD)源自测试驱动开发(TDD),将注意力集中在用户与应用程序的交互方式以及应用程序的行为方式上。 SpecBDD是BDD的一部分,它考虑应用程序的较小部分如何协同工作以使事情发生。
Sylius is installed with phpspec
which is the tool required for this. In your root directory, there’s also the phpspec.yml.dist
configuration file. Specifications are written in PHP classes and may be grouped in suites.
phpspec
随phpspec
安装,这是为此所需的工具。 在您的根目录中,还有phpspec.yml.dist
配置文件。 规范是用PHP类编写的,可以按套件分组。
Remember, Sylius is a big application so there are a lot of files. Open src/Sylius/Component/Order/spec/Model/OrderItemSpec.php
.
记住,Sylius是一个很大的应用程序,因此有很多文件。 打开src/Sylius/Component/Order/spec/Model/OrderItemSpec.php
。
The first thing to note is that no matter how deep the folder structure, you have specifications inside a spec
folder and the source code the tests apply to is easy to find. If you look at the level of the spec
folder, you’ll see Model
and inside it is an OrderItem
class. The spec for that class is spec/Model/OrderItemSpec.php
. Compare the functions and you can see how they are related.
首先要注意的是,无论文件夹结构有多深,您都可以在spec
文件夹中找到spec
并且可以轻松找到测试所应用的源代码。 如果查看spec
文件夹的级别,您会看到Model
并且在其中是一个OrderItem
类。 该类的规格为spec/Model/OrderItemSpec.php
。 比较功能,您可以看到它们之间的关系。
When you run phpspec, you get more output with the --verbose
option and with -fpretty
you can get prettier outputs.
当您运行phpspec时,使用--verbose
选项可以获得更多的输出,而使用-fpretty
可以获得更多的输出。
./bin/phpspec run -fpretty --verbose src/Sylius/Component/Order/spec/Model/OrderItemSpec.php
贝哈特 (Behat)
StoryBDD is the second side of the BDD coin which presents behavior in a narrative, focusing attention on the bigger picture of what should happen in the application. Behat is the primary tool that makes StoryBDD possible. You run Behat, it parses special files called features, and checks whether the behavior of your website matches the description in those files. Other tools are required to mimic or emulate the functionality of browsers. Mink is the library that Behat needs for that, while something like Laravel will use the excellent Dusk.
StoryBDD是BDD代币的第二面,它以叙述的形式呈现行为,将注意力集中在应用程序应该发生的事情的更广阔的画面上。 Behat是使StoryBDD成为可能的主要工具。 您运行Behat,它将解析称为功能的特殊文件,并检查您网站的行为是否与这些文件中的描述相匹配。 需要其他工具来模仿或模拟浏览器的功能。 Mink是Behat需要的库,而Laravel之类的库将使用出色的Dusk 。
The description of the behavior you write is in a format called Gherkin. Each behavior is called a scenario, and a single feature file can have multiple scenarios. The files must have an extension of feature
.
您编写的行为的描述采用称为Gherkin的格式。 每个行为都称为一个方案 ,一个功能文件可以具有多个方案。 文件必须具有feature
扩展名。
Sylius comes with a behat.yml.dist
configuration file and a features
folder with sub-folders where feature files are organized. The configuration file and features folder must be at the same level. Open features/order/managing_orders/browsing_orders.feature
and look at the structure.
behat.yml.dist
附带了一个behat.yml.dist
配置文件和一个带有子文件夹的features
文件夹,用于组织特征文件。 配置文件和功能文件夹必须处于同一级别。 打开features/order/managing_orders/browsing_orders.feature
并查看结构。
Let’s give this feature a test drive:
让我们对该功能进行测试:
./bin/behat features/order/managing_orders/browsing_orders.feature
See BDD in Laravel: Getting Started with Behat and PhpSpec for another great article on this subject.
有关此主题的另一篇出色文章,请参见《 Laravel:Behat和PhpSpec入门》中的BDD 。
做TDD (Let’s Do TDD)
We’re going to modify the Orders list page the test-driven way. Log into the admin section, admin/login
. The icon in the top left corner looks perfect, but let’s try and change it to something else. Sylius uses Semantic UI for its front-end. Take a look at the icon set. Let’s say we want to replace the “shop” with “shopping basket” icon. Viewing the source of the Orders list page, we want to go from <i class="circular shop icon"></i>
to <i class="circular shopping basket icon"></i>
.
我们将以测试驱动方式修改“订单列表”页面。 登录到admin部分admin/login
。 左上角的图标看起来很完美,但让我们尝试将其更改为其他内容。 Sylius的前端使用语义UI 。 看一下图标集 。 假设我们要用“购物篮”图标代替“商店”。 查看“订单”列表页面的来源,我们想从<i class="circular shop icon"></i>
转到<i class="circular shop icon"></i>
<i class="circular shopping basket icon"></i>
。
步骤1:添加功能 (Step 1: Add a Feature)
We aren’t starting from a blank page so we go the Sylius way. Order-related features are in features\order\managing_orders
, so we create a file there and call it browsing_orders_with_visual_display.feature
and add:
我们不是从空白页开始,所以我们走Sylius的方式。 与订单相关的功能位于features\order\managing_orders
,因此我们在此处创建一个文件,并将其命名为browsing_orders_with_visual_display.feature
并添加:
@viewing_page_icon
Feature: Browsing orders page with icon
In order to identify orders page
As an Administrator
I want to be able to see an icon on the orders page
Background:
Given the store operates on a single channel in "United States"
And the store has a product "PHP T-Shirt"
And the store ships everywhere for free
And the store allows paying with "Cash on Delivery"
And there is a customer "john.doe@gmail.com" that placed an order "#00000022"
And the customer bought a single "PHP T-Shirt"
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
@ui
Scenario: Seeing an icon on the page
When I browse orders
Then the "shopping basket" icon should be visible on the page
The Background
sets the stage for the tests. For this to work, it needs to include the channel, product, shipping method, customer details, and the user who wants to view the page. Luckily enough Sylius has done the ground work for us.
Background
为测试奠定了基础。 为此,它需要包括渠道,产品,运输方式,客户详细信息以及要查看页面的用户。 幸运的是,西里乌斯(Sylius)为我们做了基础工作。
步骤2:添加页面对象 (Step 2: Add a Page Object)
Sylius allows us to create new page objects defined in the Behat container in a etc\behat\services\pages.xml
file. We’re going to create an interface and implementation in src\Sylius\Behat\Page\Admin\Order\
.
Sylius允许我们在etc\behat\services\pages.xml
文件中的etc\behat\services\pages.xml
容器中创建新的页面对象。 我们将在src\Sylius\Behat\Page\Admin\Order\
创建一个接口和实现。
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sylius.behat.page.admin.order.order_page.class">Sylius\Behat\Page\Admin\Order\OrderPage
</parameter>
</parameters>
<services>
<service id="sylius.behat.page.admin.order.order_page" class="%sylius.behat.page.admin.order.order_page.class%"
parent="sylius.behat.page.admin.order.index" public="false">
</service>
</services>
</container>
We’re informing the Behat service container about our OrderPage
class. Let’s create src/Sylius/Behat/Page/Admin/Order/OrderPageInterface.php
:
我们正在向OrderPage
服务容器通知我们的OrderPage
类。 让我们创建src/Sylius/Behat/Page/Admin/Order/OrderPageInterface.php
:
<?php
// src/Sylius/Behat/Page/Admin/Order/OrderPageInterface.php
namespace Sylius\Behat\Page\Admin\Order;
use Sylius\Behat\Page\SymfonyPageInterface;
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
interface OrderPageInterface extends IndexPageInterface
{
/**
* Match icons by class.
*
* @param string $class
* The class to match icons against.
*
* @return mixed
* The matched icons or false.
*/
public function findIcons($class);
}
Then, src/Sylius/Behat/Page/Admin/Order/OrderPage.php
:
然后, src/Sylius/Behat/Page/Admin/Order/OrderPage.php
:
<?php
// src/Sylius/Behat/Page/Admin/Order/OrderPage.php
namespace Sylius\Behat\Page\Admin\Order;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Session;
use Sylius\Behat\Page\SymfonyPage;
use Sylius\Behat\Service\Accessor\TableAccessorInterface;
use Symfony\Component\Routing\RouterInterface;
use Sylius\Behat\Page\Admin\Crud\IndexPage;
class OrderPage extends IndexPage implements OrderPageInterface
{
/**
* @inheritDoc
*/
public function findIcons($class)
{
$foundIcons = $this->getElement('icon')->find('css', '.' . implode('.', explode(' ', $class)));
if (!$foundIcons) {
throw new ElementNotFoundException($this->getSession(), 'Icons with class(es) ' . $class);
}
return $foundIcons;
}
/**
* @inheritDoc
*/
protected function getDefinedElements()
{
return array_merge(parent::getDefinedElements(), [
'icon' => '.icon',
]);
}
}
Sylius has defined over 120 elements (classes and IDs) for identifying different things on pages but apparently not icons. (Search src\Sylius\Behat
for them). We need to find the icon
class so we define our own in the getDefinedElements()
method. Our findIcons()
method looks for the class we pass in from our feature. When icons have more than one name, such as “shopping basket”, we need to find both names.
Sylius定义了120多个元素(类和ID)来识别页面上的不同内容,但显然不是图标。 (为它们搜索src\Sylius\Behat
)。 我们需要找到icon
类,以便在getDefinedElements()
方法中定义自己的类。 我们的findIcons()
方法查找从功能中传入的类。 当图标具有多个名称(例如“购物篮”)时,我们需要找到两个名称。
步骤3:添加要运行的测试的上下文 (Step 3: Add a Context for the Tests to Run)
A context is a class that is also provided as a service. Starting from src/Sylius/Behat/Resources/config/services.xml
you’ll find <import resource="services/contexts.xml" />
near the top. Following the subsequent imports, you’ll end up in src/Sylius/Behat/Resources/config/services/contexts/
where some context categories have been configured (cli.xml
, domain.xml
, hook.xml
, setup.xml
, transform.xml
and ui.xml
). We’re after the ui.xml
one. Open it. Find the sylius.behat.context.ui.admin.managing_orders
service and we add ours just below it:
上下文是也作为服务提供的类。 从src/Sylius/Behat/Resources/config/services.xml
您将在顶部附近找到<import resource="services/contexts.xml" />
。 在随后的导入之后,您将最终进入src/Sylius/Behat/Resources/config/services/contexts/
,其中已配置了一些上下文类别( cli.xml
, domain.xml
, hook.xml
, setup.xml
, transform.xml
和ui.xml
)。 我们在ui.xml
之后。 打开它。 找到sylius.behat.context.ui.admin.managing_orders
服务,然后在下面添加我们的服务:
<service id="sylius.behat.context.ui.admin.viewing_page_icon" class="Sylius\Behat\Context\Ui\Admin\ViewingPageIconContext">
<argument type="service" id="sylius.behat.page.admin.order.order_page" />
<tag name="fob.context_service" />
</service>
Note the relationship between the service id
and class
. Dots are replaced with backslashes and camel-casing of class names.
注意服务id
和class
之间的关系。 点被类名的反斜杠和骆驼框代替。
Create src\Sylius\Behat\Context\Ui\Admin\ViewingPageIconContext.php
and add this:
创建src\Sylius\Behat\Context\Ui\Admin\ViewingPageIconContext.php
并添加以下内容:
<?php
// src/Sylius/Behat/Context/Ui/Admin/ViewingPageIconContext.php
namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
use Sylius\Behat\Page\Admin\Order\OrderPageInterface;
use Webmozart\Assert\Assert;
use Behat\Behat\Tester\Exception\PendingException;
class ViewingPageIconContext implements Context
{
/**
* @var OrderPageInterface
*/
private $orderPage;
/**
* @param OrderPageInterface $orderPage
*/
public function __construct(OrderPageInterface $orderPage)
{
$this->orderPage = $orderPage;
}
/**
* @Then /^the "([^"]*)" icon should be visible on the page$/
*/
public function theIconShouldBeVisibleOnThePage($class)
{
$icons = $this->orderPage->findIcons($class);
Assert::eq(count($icons), 1, sprintf('Icon with class, %s, not found', $class));
}
}
We inject our OrderPageInterface
into this class so that when Behat finds our scenario, we’re able to call the right method from the injected class. We expect only one icon and we assert it.
我们将OrderPageInterface
注入到此类中,以便OrderPageInterface
找到我们的场景时,我们能够从注入的类中调用正确的方法。 我们只希望有一个图标,并且可以断言它。
Let’s run our test. It fails because there’s no shopping basket icon yet. Now we can go ahead and make the change. Open src/Sylius/Bundle/AdminBundle/Resources/config/routing/order.yml
and change icon: cart
to icon: shopping basket
. Run the test and it should be green.
让我们进行测试。 它失败,因为还没有购物篮图标。 现在我们可以继续进行更改。 打开src/Sylius/Bundle/AdminBundle/Resources/config/routing/order.yml
并将icon: cart
更改为icon: shopping basket
。 运行测试,它应该是绿色的。
Next, we make a couple of other changes. Our store is a single-channel business, so we don’t need the Channel column. Secondly, we want the table row to have a different background depending on the state. For this, we’ll write another test before making the change. Cancel one or two orders in the admin section so that we have different states.
接下来,我们进行其他一些更改。 我们的商店是一家单渠道商家,因此我们不需要“渠道”列。 其次,我们希望表格行根据状态而具有不同的背景。 为此,我们将在进行更改之前编写另一个测试。 在管理部分中取消一两个订单,以便我们拥有不同的状态。
Update our feature file
features\order\managing_orders\browsing_orders_with_visual_display.feature
with this:使用以下命令更新功能文件
features\order\managing_orders\browsing_orders_with_visual_display.feature
:@ui Scenario: Checking row of a cancelled order When I view the summary of the order "#00000022" And I cancel this order When I browse orders Then this order should have order payment state "Cancelled" And the row should be marked with the order payment state "Cancelled"
We’ll also update
OrderPageInterface
andOrderPage
:我们还将更新
OrderPageInterface
和OrderPage
:// src/Sylius/Behat/Page/Admin/Order/OrderPageInterface.php /** * Match table rows by class. * * @param string $class * The class to match table rows against. * * @return mixed * The matched rows or false. */ public function findTableRows($class);
// src/Sylius/Behat/Page/Admin/Order/OrderPage.php /** * @inheritDoc */ public function findTableRows($class) { $foundRows = $this->getElement('table')->find('css', '.' . $class); if (!$foundRows) { throw new ElementNotFoundException($this->getSession(), 'Rows with class ' . $class); } return $foundRows; }
The table element is already defined in Sylius so we just use it. We find all rows with the class passed in. When you run the test, it’s red. Now we can make the necessary changes.
table元素已经在Sylius中定义,因此我们只使用它。 我们找到所有传入类的行。运行测试时,它为红色。 现在我们可以进行必要的更改。
Override “State” and “Channel” columns in the
sylius_admin_order
grid, defined insrc/Sylius/Bundle/AdminBundle/Resources/config/grids/order.yml
.覆盖
sylius_admin_order
网格中的“状态”和“通道”列,这些列在src/Sylius/Bundle/AdminBundle/Resources/config/grids/order.yml
。Create
app\config\grids.yml
and add this:创建
app\config\grids.yml
并添加以下内容:
sylius_grid: grids: sylius_admin_order: fields: channel: enabled: false state: enabled: false
Tell Sylius about this file by importing it in
app\config\config.yml
:通过将其导入
app\config\config.yml
该文件:
sylius_grid: grids: sylius_admin_order: fields: channel: enabled: false state: enabled: false
- { resource: "grids.yml" }
Copy
src\Sylius\Bundle\UiBundle\Resources\views\Macro\table.html.twig
toapp\Resources\SyliusUiBundle\views\Macro\table.html.twig
and in the{% macro row(grid, definition, row) %}
statement, replace<tr class="item">
with<tr class="item {{ row.state | lower }}">
. All we have to do is add CSS for the output classes here.将
src\Sylius\Bundle\UiBundle\Resources\views\Macro\table.html.twig
到app\Resources\SyliusUiBundle\views\Macro\table.html.twig
并在{% macro row(grid, definition, row) %}
语句,将<tr class="item">
替换为<tr class="item {{ row.state | lower }}">
。 我们要做的就是在此处为输出类添加CSS。Copy
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\PaymentState\awaiting_payment.html.twig
toapp\Resources\SyliusAdminBundle\views\Order\Label\PaymentState\awaiting_payment.html.twig
. We want the icon and the label to be uppercase. Change the file to this:将
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\PaymentState\awaiting_payment.html.twig
到app\Resources\SyliusAdminBundle\views\Order\Label\PaymentState\awaiting_payment.html.twig
。 我们希望图标和标签为大写。 将文件更改为此:<span class="ui olive label"> {{ value|trans|upper }} </span>
Copy
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\PaymentState\cancelled.html.twig
toapp\Resources\SyliusAdminBundle\views\Order\Label\PaymentState\cancelled.html.twig
. Change the file to this:将
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\PaymentState\cancelled.html.twig
到app\Resources\SyliusAdminBundle\views\Order\Label\PaymentState\cancelled.html.twig
。 将文件更改为此:<span class="ui yellow label"> {{ value|trans|upper }} </span>
Copy
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\ShippingState\cancelled.html.twig
toapp\Resources\SyliusAdminBundle\views\Order\Label\ShippingState\cancelled.html.twig
. We do the same as above:将
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\ShippingState\cancelled.html.twig
app\Resources\SyliusAdminBundle\views\Order\Label\ShippingState\cancelled.html.twig
到app\Resources\SyliusAdminBundle\views\Order\Label\ShippingState\cancelled.html.twig
。 我们做与上面相同:<span class="ui yellow label"> {{ value|trans|upper }} </span>
Copy
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\ShippingState\ready.html.twig
toapp\Resources\SyliusAdminBundle\views\Order\Label\ShippingState\ready.html.twig
. We do the same as above:将
src\Sylius\Bundle\AdminBundle\Resources\views\Order\Label\ShippingState\ready.html.twig
到app\Resources\SyliusAdminBundle\views\Order\Label\ShippingState\ready.html.twig
。 我们做与上面相同:<span class="ui blue label"> {{ value|trans|upper }} </span>
Copy
src\Sylius\Bundle\UiBundle\Resources\views\_stylesheets.html.twig
toapp\Resources\SyliusUiBundle\views\_stylesheets.html.twig
. Here we add our custom CSS file just below the default:<link rel="stylesheet" href="{{ asset('assets/admin/css/style.css') }}">
. There are other ways of doing this but this is the quickest way to keep our changes isolated.将
src\Sylius\Bundle\UiBundle\Resources\views\_stylesheets.html.twig
到app\Resources\SyliusUiBundle\views\_stylesheets.html.twig
。 在这里,我们在默认值以下添加我们的自定义CSS文件:<link rel="stylesheet" href="{{ asset('assets/admin/css/style.css') }}">
。 还有其他方法可以做到这一点,但这是使我们的更改保持隔离的最快方法。Add
assets/admin/css/style.css
with our magnificent CSS.用我们宏伟CSS添加
assets/admin/css/style.css
。.order-row.new { background-color: #c5effd; } .order-row.cancelled { background-color: #fbe7af; }
Run the test again. It’s all green.
再次运行测试。 都是绿色的。
Refresh the orders page but you may also need to clear the cache first. Cancelled orders rows now have a different background color.
刷新订单页面,但您可能还需要先清除缓存。 现在,已取消的订单行具有不同的背景颜色。
Finally, let’s add a test to assert that the Channel column is no more.
最后,让我们添加一个测试来断定Channel列不再存在。
Update our feature file
features\order\managing_orders\browsing_orders_with_visual_display.feature
with this:使用以下命令更新功能文件
features\order\managing_orders\browsing_orders_with_visual_display.feature
:Scenario: Not seeing a column on the page When I browse orders Then the "channel" column should not be visible on the page
Update
OrderPageInterface.php
with:使用以下命令更新
OrderPageInterface.php
:// src/Sylius/Behat/Page/Admin/Order/OrderPageInterface.php /** * Get table headers. * * @return mixed * The array of headers keys or empty array. */ public function findTableHeaders();
Implement the new method in
OrderPage.php
:在
OrderPage.php
实现新方法:// src/Sylius/Behat/Page/Admin/Order/OrderPage.php /** * {@inheritdoc} */ public function findTableHeaders() { $headers = $this->getTableAccessor() ->getSortableHeaders($this->getElement('table')); return is_array($headers) ? array_keys($headers) : array(); }
Sylius comes with a
TableAccessor
class with a lot of useful methods for working with tables in tests. The default table headers are sortable and we simply call the method that fetches all sortableth
elements on the page.TableAccessor
带有TableAccessor
类,该类具有许多在测试中处理表的有用方法。 默认的表头可排序,我们简单地调用获取所有排序的方法th
页面上的元素。Update our feature context
ViewingPageIconContext.php
:更新我们的功能上下文
ViewingPageIconContext.php
:// src\Sylius\Behat\Context\Ui\Admin\ViewingPageIconContext.php /** * @Then /^the "([^"]*)" column should not be visible on the page$/ */ public function theColumnShouldNotBeVisibleOnThePage($column) { $foundHeaders = $this->orderPage->findTableHeaders(); Assert::false(in_array(strtolower($column), $foundHeaders), sprintf('%s column not found', $column)); }
We get all table headers on the order page. The array of header elements is keyed by name e.g. date, customer, channel, number, paymentState, shippingState etc. representing the columns. We check the keys to confirm that our column is no longer on the page.
我们在订单页面上获得所有表头。 标题元素数组由名称(例如代表列的日期,客户,渠道,编号,paymentState,shippingState等)键入。 我们检查键以确认我们的列不再在页面上。
结论 (Conclusion)
These are baby steps designed to illustrate a TDD process – think of what you want to achieve, write tests to check when it’s done, tests fail, make the changes required, and tests pass.
这些是旨在说明TDD流程的简单步骤-思考您要实现的目标,编写测试以检查其完成时间,测试失败,进行所需的更改并通过测试。
We’ve explored StoryBDD by writing a couple of Behat tests to demonstrate this process. Although these are simple examples, the same principles apply when doing more complex things or working with SpecBDD or PHPUnit tests.
我们通过编写几个Behat测试来演示此过程,从而探索了StoryBDD。 尽管这些都是简单的示例,但是在执行更复杂的操作或使用SpecBDD或PHPUnit测试时,也适用相同的原理。
Which approach do you take when testing? Only TDD? Only BDD? Both? Maybe BDDed TDD? Let us know!
测试时采取哪种方法? 只有TDD? 只有BDD? 都? 也许是BDD TDD ? 让我们知道!
翻译自: https://www.sitepoint.com/sylius-and-cutting-your-teeth-on-tdd/
tdd和ddd