PHP 怎么Behat测试

wen PHP项目 6

本文目录导读:

PHP 怎么Behat测试

  1. Behat简介
  2. 安装Behat
  3. 项目结构
  4. 创建Feature文件
  5. 配置behat.yml
  6. 编写FeatureContext
  7. 运行Behat测试
  8. 使用数据表
  9. 使用正则表达式
  10. 高级特性
  11. 最佳实践
  12. 与CI/CD集成

我来详细讲解PHP中使用Behat进行行为驱动开发(BDD)测试的方法。

Behat简介

Behat是PHP的BDD测试框架,用于测试应用程序的业务行为,它允许你用人类可读的语言描述功能,然后自动验证。

安装Behat

使用Composer安装

# 创建项目目录
mkdir my-project
cd my-project
# 初始化composer
composer init
# 安装Behat
composer require --dev behat/behat
# 初始化Behat项目结构
vendor/bin/behat --init

项目结构

初始化后,Behat会创建以下结构:

my-project/
├── features/
│   ├── bootstrap/
│   │   └── FeatureContext.php
│   └── *.feature
├── vendor/
├── behat.yml
└── composer.json

创建Feature文件

示例功能:用户登录

features/login.feature

Feature: 用户登录
  作为用户
  我需要能够登录系统
  以便访问我的账户
  Scenario: 使用正确的凭据登录
    Given 我在登录页面
    When 我输入用户名 "john@example.com"
    And 我输入密码 "password123"
    And 我点击登录按钮
    Then 我应该看到欢迎消息 "欢迎,John"
    And 我应该被重定向到仪表盘
  Scenario: 使用错误的凭据登录
    Given 我在登录页面
    When 我输入用户名 "john@example.com"
    And 我输入密码 "wrongpassword"
    And 我点击登录按钮
    Then 我应该看到错误消息 "密码错误"

配置behat.yml

behat.yml

default:
  autoload:
    '': '%paths.base%/features/bootstrap'
  suites:
    default:
      paths:
        - '%paths.base%/features'
      contexts:
        - FeatureContext
  extensions:
    Behat\MinkExtension:
      base_url: http://localhost
      browser_name: chrome
      sessions:
        default:
          selenium2:
            wd_host: http://localhost:9515

编写FeatureContext

features/bootstrap/FeatureContext.php

<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;
class FeatureContext extends MinkContext implements Context
{
    private array $users = [];
    private string $currentUser = '';
    public function __construct()
    {
        // 初始化测试数据
        $this->users = [
            'john@example.com' => [
                'password' => 'password123',
                'name' => 'John'
            ]
        ];
    }
    /**
     * @Given 我在登录页面
     */
    public function iAmOnLoginPage()
    {
        $this->visit('/login');
    }
    /**
     * @When 我输入用户名 :username
     */
    public function iEnterUsername($username)
    {
        $this->fillField('email', $username);
        $this->currentUser = $username;
    }
    /**
     * @When 我输入密码 :password
     */
    public function iEnterPassword($password)
    {
        $this->fillField('password', $password);
    }
    /**
     * @When 我点击登录按钮
     */
    public function iClickLoginButton()
    {
        $this->pressButton('login');
    }
    /**
     * @Then 我应该看到欢迎消息 :message
     */
    public function iShouldSeeWelcomeMessage($message)
    {
        $this->assertPageContainsText($message);
    }
    /**
     * @Then 我应该被重定向到仪表盘
     */
    public function iShouldBeRedirectedToDashboard()
    {
        $this->assertPageAddress('/dashboard');
    }
    /**
     * @Then 我应该看到错误消息 :message
     */
    public function iShouldSeeErrorMessage($message)
    {
        $this->assertPageContainsText($message);
    }
    /**
     * @Given 存在以下用户
     */
    public function thereAreUsers(TableNode $table)
    {
        foreach ($table as $row) {
            $this->users[$row['email']] = [
                'password' => $row['password'],
                'name' => $row['name']
            ];
        }
    }
}

运行Behat测试

# 运行所有测试
vendor/bin/behat
# 运行指定文件
vendor/bin/behat features/login.feature
# 运行指定场景
vendor/bin/behat features/login.feature:8
# 带格式化输出
vendor/bin/behat --format=pretty
# 严格模式
vendor/bin/behat --strict

使用数据表

features/products.feature

Feature: 产品管理
  作为管理员
  我需要管理产品
  以便更新商城信息
  Scenario: 添加多个产品
    Given 管理员已登录
    When 我添加以下产品:
      | 名称      | 价格  | 库存 |
      | 苹果      | 5.00  | 100  |
      | 香蕉      | 3.50  | 200  |
      | 橙子      | 4.00  | 150  |
    Then 产品列表应该包含 3 个产品

ProductContext.php

<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
class ProductContext implements Context
{
    private array $products = [];
    /**
     * @When 我添加以下产品:
     */
    public function iAddProducts(TableNode $table)
    {
        foreach ($table as $row) {
            $this->products[] = [
                'name' => $row['名称'],
                'price' => (float)$row['价格'],
                'stock' => (int)$row['库存']
            ];
        }
    }
    /**
     * @Then 产品列表应该包含 :count 个产品
     */
    public function productListShouldContain($count)
    {
        $actualCount = count($this->products);
        if ($actualCount !== (int)$count) {
            throw new \Exception("Expected $count products, got $actualCount");
        }
    }
}

使用正则表达式

/**
 * @When /^我输入(用户名|密码) "([^"]*)"$/
 */
public function iEnterField($field, $value)
{
    if ($field === '用户名') {
        $this->fillField('email', $value);
    } else {
        $this->fillField('password', $value);
    }
}

高级特性

场景大纲(Scenario Outline)

Feature: 计算器
  作为用户
  我需要使用计算器
  以便进行数学运算
  Scenario Outline: 加法运算
    Given 我输入 <num1>
    And 我输入 <num2>
    When 我执行加法
    Then 结果应该是 <result>
    Examples:
      | num1 | num2 | result |
      | 1    | 2    | 3      |
      | 10   | 20   | 30     |
      | 5    | 7    | 12     |

后台(Background)

Feature: 用户管理
  Background:
    Given 管理员已登录
    And 存在以下用户:
      | name | email           |
      | John | john@test.com   |
      | Jane | jane@test.com   |
  Scenario: 查看用户列表
    When 我访问用户列表
    Then 我应该看到 2 个用户

标签(Tags)

Feature: 复杂功能
  @smoke @critical
  Scenario: 关键功能测试
    Given 基础配置
    And 额外配置
  @wip @slow
  Scenario: 开发中功能
    Given 开发中的功能

运行带标签的测试:

vendor/bin/behat --tags=@smoke
vendor/bin/behat --tags="@wip&&~@slow"

最佳实践

  1. 使用清晰的语言:Feature文件应使用业务语言,避免技术细节
  2. 保持步骤简洁:每个步骤只做一件事
  3. 使用数据驱动:利用Scenario Outline减少重复
  4. 维护测试数据:使用Fixture或Factory模式
  5. 合理的目录结构:按功能模块组织Feature文件
features/
├── authentication/
│   ├── login.feature
│   └── registration.feature
├── products/
│   ├── create.feature
│   ├── edit.feature
│   └── delete.feature
└── bootstrap/
    └── FeatureContext.php

与CI/CD集成

GitHub Actions (.github/workflows/behat.yml)

name: Behat Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.0'
      - run: composer install
      - run: vendor/bin/behat

Behat提供了一套强大的BDD测试框架,主要优势:

  • 业务人员和开发人员可以共享相同语言
  • 自动生成文档
  • 易于维护
  • 强类型断言

Behat不只是测试工具,更是沟通工具,能帮助团队更好地理解需求。

抱歉,评论功能暂时关闭!