用Codeception统治(测试)群

What happens if you have more tests then zergs in the swarm? Really much more. You should find a way to control and manage them. In this article I’ll share some hints and best practices you may use writing acceptance tests. I’ll use Codeception testing framework to illustrate the best practices, but surely, they can be ported to any acceptance framework you use for testing.

如果您要进行的测试多于虫族,那会发生什么? 真的更多。 您应该找到一种控制和管理它们的方法。 在本文中,我将分享一些提示和最佳实践,您可以使用它们编写验收测试。 我将使用Codeception测试框架来说明最佳实践,但是可以肯定的是,可以将它们移植到用于测试的任何接受框架中。

进入代码接收 (Into Codeception)

Designing and building a great web application means that our workflow and architecture allow for constant improvement to the product. In order to make our products stable and to have confidence that new commits have no adverse-effect on existing code, we use automated testing practices. And just as we need a proper architecture for our application, we need to design a proper architecture for our testing platform.

设计和构建出色的Web应用程序意味着我们的工作流程和体系结构允许不断改进产品。 为了使我们的产品稳定并确保新提交不会对现有代码产生不利影响,我们使用自动化测试实践。 正如我们需要为应用程序提供适当的体系结构一样,我们也需要为测试平台设计适当的体系结构。

A testing platform is a complete infrastructure over our tests. And when I say tests, I don’t mean only unit tests. Think wider. The application also needs to be tested in a browser with Selenium (or an alternative). So we need unit tests, Selenium tests, probably API tests, and all of them should be executed together. Somehow. I’d like to introduce you Codeception – a modern PHP testing framework built on top of Symfony2 components, Mink, and PHPUnit.

测试平台是我们测试的完整基础架构。 当我说测试时,我并不是指仅单元测试。 考虑范围更广。 还需要在使用Selenium(或替代品)的浏览器中测试该应用程序。 因此,我们需要单元测试,Selenium测试,可能是API测试,并且所有这些都应一起执行。 不知何故。 我想向您介绍Codeception,这是一个基于Symfony2组件,Mink和PHPUnit构建的现代PHP测试框架。

Codeception includes more than 20 modules to test over popular PHP frameworks, APIs (REST, SOAP), data stores (MySQL, PostgreSQL, MongoDB, etc) and web with Selenium WebDriver. Check it out on the official web site: codeception.com

Codeception包括20多个模块,可通过Selenium WebDriver对流行PHP框架,API(REST,SOAP),数据存储(MySQL,PostgreSQL,MongoDB等)和Web进行测试。 在官方网站上查看: codeception.com

And what better way to run all of these tests than on an Continuous Integration server after each commit? I recommend using Codeception as the main block for your test automation platform; Codeception can execute Selenium tests, API tests, and PHPUnit tests all in one and generate complete HTML and XML reports for CI systems. It can even generate a complete code coverage report for all of the tests.

还有什么比每次提交后在Continuous Integration服务器上运行所有这些测试更好的方法? 我建议将Codeception用作测试自动化平台的主要模块; Codeception可以一次执行Selenium测试,API测试和PHPUnit测试,并为CI系统生成完整HTML和XML报告。 它甚至可以为所有测试生成完整的代码覆盖率报告。

It’s pretty easy to start writing tests with Codeception. You can teach your QAs to write such tests since only a very basic knowledge of PHP is required to start. I’ll leave you to discover the basics of Codeception on your own, since what I want to tell you here is how Codeception can help you build a better test automation platform.

使用Codeception开始编写测试非常容易。 您可以教您的QA编写此类测试,因为仅需具备非常基础PHP知识即可。 我将让您自己探索Codeception的基础知识,因为在这里我想告诉您的是Codeception如何帮助您构建更好的测试自动化平台。

测试单元 (Hive of Tests)

It’s not enough to say “We are writing tests” or “We practice TDD/BDD”. What you should be aiming for is the creation of a solid test automation platform. It doesn’t really matter if you’re writing your tests before code, or code before tests, or tests described as a story (in BDD-way), or tests as code. What really matters is how you manage all of these tests.

仅说“我们正在编写测试”或“我们练习TDD / BDD”还不够。 您应该瞄准的是创建可靠的测试自动化平台。 是在代码之前编写测试,还是在代码之前编写测试,还是描述为故事的测试(以BDD方式),还是作为代码进行测试,这并不重要。 真正重要的是如何管理所有这些测试。

There may be more then 1,000 or 10,000 or 100,000 tests, and they may run for a three or four hours. You need keep the code for your tests clean and simple. Tests should be easy to refactor (as they constantly change with application) and they should be easy to extend. Basically, you should follow the same best practices you use for writing production code when writing testing code.

可能会有1,000或10,000或100,000多个测试,它们可能需要运行三四个小时。 您需要保持测试代码简洁明了。 测试应该易于重构(因为它们随应用程序不断变化),并且应该易于扩展。 基本上,编写测试代码时,应该遵循与编写生产代码相同的最佳实践。

基本测试 (A Basic Test)

Here is a sample acceptance test in Codeception. In this scenario I’m sending an invite to a friend from a website. To test this I need to be logged in, generate an invitation code, and then try to register a new user with the code. Here is how the scenario could look in Codeception:

这是Codeception中的样本接受测试。 在这种情况下,我正在从网站向朋友发送邀请。 要对此进行测试,我需要登录,生成邀请代码,然后尝试使用该代码注册新用户。 这是该方案在Codeception中的外观:

<?php
$I = new WebGuy($scenario);
$I->wantTo('generate invitation code and sign up using it');
$I->amOnPage('/login');
$I->fillField('Username','tester1');
$I->fillField('Password','123456');
$I->click('Sign In');
$I->see('Hello, tester1');
$I->click('Invite');
$I->see('Copy this invitation code');
$code = $I->grabTextFrom('#invitation_code');
$I->click('Logout');
$I->amOnPage('/register');
$I->see('You can sign up if you have invitation code!', 'h1');
$I->fillField('Invitation Code', $code);
$I->fillField('Username','tester2');
$I->fillField('Password','654321');
$I->click('#invite_form input[type=submit]');
$I->see('Hello, tester2');

Even if you’re not familiar with Codeception, this test should be pretty readable; all actions are described from a user’s perspective and no special technical terms are used here. This test may look simple and clean, but if you have such tests then you should consider refactoring it. And here is why…

即使您不熟悉Codeception,该测试也应该可读性强; 所有操作均从用户角度进行描述,此处不使用特殊技术术语。 该测试可能看起来简单干净,但是如果您有这样的测试,则应考虑对其进行重构。 这就是为什么……

设计模式:页面对象 (Design Pattern: Page Object)

You should avoid hard-coded values directly in your tests whenever you can as this will make the tests more stable to changes. Suppose similar login and signup forms are used in other tests. If the username field was renamed to “Login” then you’d need to rewrite the tests that use login. We can use the Page Object pattern and CSS/XPath to locate elements on a page. The same goes for the Invite page.

您应尽可能避免在测试中直接使用硬编码的值,因为这样会使测试对更改更稳定。 假设在其他测试中使用类似的登录和注册表单。 如果用户名字段重命名为“登录”,那么您需要重写使用登录的测试。 我们可以使用Page Object模式和CSS / XPath来定位页面上的元素。 邀请页面也是如此。

A Page Object is an entity that represents a page (or several typical pages) of your site, a can be written as a class with static properties and methods.

Page Object是代表您网站的一个页面(或几个典型页面)的实体,可以将a编写为具有静态属性和方法的类。

<?php
class InvitePage
{
    // URL of a page
    public static $URL = '/register';
    // This properties define a UI map for Login Page
    public static $codeField = "Invitation Code";
    public static $usernameField = "Username";
    public static $passwordField = "Password";
    public static $submitButton = "#invite_form input[type=submit]";
}

Now part of the test can be rewritten in this manner:

现在可以以这种方式重写部分测试:

<?php
$I->amOnPage(InvitePage::$URL);
$I->fillField(InvitePage::$codeField, $code);
$I->fillField(InvitePage::$usernameField,'tester2');
$I->fillField(InvitePage::$passwordField,'654321');
$I->click(InvitePage::$submitButton);

In this case, all tests visiting the Invite page use the same variables for locating elements on the page. If any element changes its position, you can update the InvitePage class as needed without touching the tests themselves.

在这种情况下,所有访问“邀请”页面的测试都使用相同的变量来定位页面上的元素。 如果任何元素更改了其位置,则可以根据需要更新InvitePage类,而无需接触测试本身。

设计模式:控制器 (Design Pattern: Controller)

We’ve removed some hardcoded variables from the test, but what happens if you introduce two-factor authentication to the web application you’re developing. What does it mean for your tests? It means that you’ll need to update all of the tests that requires an authorized user to run. I will remind you: there may be thousands and of tests. It would be natural to move some scenario logic into a class so we can reuse the log in/out and signup scenarios in other tests.

我们已经从测试中删除了一些硬编码的变量,但是如果您向正在开发的Web应用程序引入两因素身份验证,会发生什么情况。 对您的测试意味着什么? 这意味着您需要更新所有需要授权用户才能运行的测试。 我会提醒您:可能有成千上万的测试。 将某些场景逻辑移到一个类中是很自然的,因此我们可以在其他测试中重用登录/注销和注册场景。

I asked some automation engineer friends how they refer to such a class. They used the term Step Object (which is common in BDD), but I’d rather call it a Controller here because of the similarity it has with the controllers we use in web applications. There are no strict rules stating what page objects or step objects should look like; you are free to build them as you wish. Here is an example controller I would use for Codeception test:

我问了一些自动化工程师朋友,他们如何指称此类。 他们使用了术语“ Step Object”(在BDD中很常见),但是在这里我宁愿称其为Controller,因为它与我们在Web应用程序中使用的控制器相似。 没有严格的规则说明页面对象或步骤对象应该是什么样。 您可以随意构建它们。 这是我将用于Codeception测试的示例控制器:

<?php
class UserController
{
    protected $user;

    public function __construct(WebGuy $I) {
        $this->user = $I;
    }

    public function login($username, $password) {
        $this->user->amOnPage(LoginPage::$URL);
        $this->user->fillField(LoginPage::$usernameField, $username);
        $this->user->fillField(LoginPage::$passwordField, $password);
        $this->user->click(LoginPage::$submitButton);
        $this->user->see("Hello, $username");
    }

    public function logout() {
        $this->user->click("Logout");
    }

    public function registerWithInviteCode($code, $username, $password) {
        $this->user->amOnPage(InvitePage::$URL);
        $this->user->fillField(InvitePage::$codeField, $code);
        $this->user->fillField(InvitePage::$usernameField, $username);
        $this->user->fillField(InvitePage::$passwordField, $password);
        $this->user->click(InvitePage::$submitButton);
    }
}

Now the code has logical blocks and the scenario will look much cleaner:

现在,代码具有逻辑块,场景将变得更加清晰:

<?php
$I = new WebGuy($scenario);
$U = new UserController($I);
$I->wantTo('generate invitation code and sign up using it');
$U->login('tester1', '123456');
$I->click('Invite');
$I->see('Copy this invitation code');
$code = $I->grabTextFrom('#invitation_code');
$U->logout();
$U->registerWithInviteCode($code, 'tester2', '654321');
$I->see('Hello, tester2');

By introducing controllers and page objects, we’ve gotten rid of most hardcoded values and common scenario steps. It can log users in from other tests, and that’s really useful as probably most of your application’s functionality is available only to authorized users. You can write 10 or 100 or even 1,000 tests, but using page objects and controllers they won’t make a mess and will be easy to support.

通过引入控制器和页面对象,我们摆脱了大多数硬编码值和常见方案步骤。 它可以从其他测试中登录用户,这确实很有用,因为您的大多数应用程序功能仅对授权用户可用。 您可以编写10或100甚至1,000个测试,但是使用页面对象和控制器不会使他们一团糟,并且易于支持。

向指挥官报告 (Report to the Commander)

Because of the refactoring, the test code has probably lost some of its readability to non-developers. Luckily, Codeception can help with that, too. Codeception will show you all scenario steps that were executed when running the test:

由于重构,测试代码可能已对非开发人员失去了部分可读性。 幸运的是,Codeception也可以提供帮助。 Codeception将向您显示在运行测试时执行的所有方案步骤:

$ ./codecept.phar run acceptance --steps
Codeception PHP Testing Framework v1.5.5
Powered by PHPUnit 3.7.14 by Sebastian Bergmann.

Suite acceptance started
Trying to generate invitation code and sign up using it (InviteCept.php)
Scenario:
* I am on page '/login'
* I fill field 'Username','tester1'
* I fill field 'Password','123456'
* I click 'Sign In'
* I see 'Hello, tester1'
* I click 'Invite'
* I see 'Copy this invitation code'
* I grab text from '#invitation_code'
* I click 'Logout'
* I am on page '/register'
* I see 'You can sign up if you have invitation code!', 'h1'
* I fill field 'Invitation Code', 'iuSia89ak'
* I fill field 'Username','tester2'
* I fill field 'Password','654321'
* I click '#invite_form input[type=submit]'
* I see 'Hello, tester2'

Time: 10 seconds, Memory: 26.00Mb
OK (1 test, 4 assertions)

In this case the output is readable. This scenario can even be shown to a non-technical person, to a manager, or a business analyst, and they’ll understand what is happening. Codeception allows you to generate HTML reports written in a similar manner. They can be shown to managers or business analysts to demonstrate what and how you you’re your application.

在这种情况下,输出是可读的。 甚至可以将这种情况显示给非技术人员,经理或业务分析师,他们将了解发生了什么。 使用Codeception,您可以生成以类似方式编写HTML报告。 它们可以显示给经理或业务分析师,以证明您的应用程序以及应用程序的方式。

结论 (Conclusion)

Nowadays test automation engineers prefer Java and Ruby, but as a PHP developer you’re undoubtedly interested in testing platforms that play well with your PHP code and is written in PHP itself. Codeception is a great tool to easily start acceptance testing, and it’s flexible enough to build a solid test automation platform.

如今,测试自动化工程师更喜欢Java和Ruby,但作为PHP开发人员,您无疑对测试平台很感兴趣,这些平台可以很好地与PHP代码一起使用并且由PHP本身编写。 Codeception是轻松启动验收测试的好工具,并且足够灵活以构建可靠的测试自动化平台。

But no matter what framework you use, keep in mind that it’s not enough just to write tests. To make tests clean, stable, and maintainable, use the KISS and DRY principles you already know. Design patterns like Page Object and Controller (Step Object) will help you in that.

但是,无论使用哪种框架,请记住,仅编写测试是不够的。 为了使测试干净,稳定和可维护,请使用您已经知道的KISS和DRY原理。 诸如页面对象和控制器(步骤对象)之类的设计模式将帮助您。

Image via Fotolia

图片来自Fotolia

翻译自: https://www.sitepoint.com/ruling-the-swarm-of-tests-with-codeception/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值