标签: phpunit

为什么PHPunit使用Silex要求KERNEL_DIR?

我正在尝试为我的Silex应用程序设置单元测试,但我不断收到此错误消息:

RuntimeException:根据http://symfony.com/doc/current/book/testing.html#your-first-functional-test在phpunit.xml中设置KERNEL_DIR 或覆盖WebTestCase :: createKernel()方法.

这是我的./app/phpunit.xml.dist:

<?xml version="1.0" encoding="UTF-8"?>

<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit
    backupGlobals="false"
    backupStaticAttributes="false"
    colors="true"
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    processIsolation="false"
    stopOnFailure="false"
    syntaxCheck="false"
    bootstrap="phpunit_bootstrap.php"
>
    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>../src/Acme/*/Tests</directory>
        </testsuite>
    </testsuites>

    <!--<php>-->
        <!--<server name="KERNEL_DIR" value="/var/www/acme/api/app/" />-->
    <!--</php>-->
</phpunit>
Run Code Online (Sandbox Code Playgroud)

这是我的./app/phpunit_bootstrap.php(包括作曲家的自动加载器):

<?php

if (!@include __DIR__ . '/../../vendor/autoload.php') {
    die(<<<'EOT'
You must set up the project dependencies, run the following commands:
wget http://getcomposer.org/composer.phar
php composer.phar install
EOT
    );
}
Run Code Online (Sandbox Code Playgroud)

我的目录结构如下:

Silex应用程序树结构

它看起来像是phpunit在找,*Kernel.php但我不知道为什么.

这是我的单元测试: …

phpunit unit-testing silex

6
推荐指数
1
解决办法
3076
查看次数

使用vendor目录中的autoloader.php自动加载无法正常工作

由于自动加载器无法解析Doctrine\ORM\Mapping\Table,因此我很难对作曲家进行自动加载.对于Unittests,我创建了带有典型Annotations的doctrine实体类:

<?php

namespace OmniSearchTest\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Picture
 *
 * @ORM\Table(name="picture")
 * @ORM\Entity
 */
class Picture
{
Run Code Online (Sandbox Code Playgroud)

并使用此实体创建了一个新的实体管理器.但我收到消息:

Doctrine\Common\Annotations\AnnotationException: [Semantical Error] The annotation "@Doctrine\ORM\Mapping\Table" in class OmniSearchTest\Entity\Picture does not exist, or could not be auto-loaded.
Run Code Online (Sandbox Code Playgroud)

对于一些Unittests

首先,我有以下项目结构:

/src
    /OmniSearch
        SomeClass.php
/tests
    /OmniSearchTest
        SomeClassTest.php
/composer.json
/phpunit.xml.dist
Run Code Online (Sandbox Code Playgroud)

我的composer.json看起来像这样:

{
    /* ... */

    "require": {
        "php": ">=5.4",
        "doctrine/orm": "2.*"
    },
    "require-dev": {
        "phpunit/phpunit": "4.*"
    },
    "autoload": {
        "psr-0": {
            "OmniSearch\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-0": {
            "OmniSearchTest\\": "tests/"
        } …
Run Code Online (Sandbox Code Playgroud)

php phpunit autoload doctrine-orm composer-php

6
推荐指数
1
解决办法
5445
查看次数

PHPUnit -setUp() - 它是在每个测试用例之前和之后运行的吗?

setup()在PHPUnit中仍然有点困惑.

它是每个测试用例之前之后 运行的吗?

对于intance,我想在每次测试之前清理我的文章表,但是我想保留已经注入表中的测试数据.因为我只想清洁它直到下一次测试.

我的测试,

namespace Test\Foo\Article;

use Test\SuiteTest;
use Foo\Article;

class ArticleTest extends SuiteTest
{
    protected static $Article;

    /**
     * Call this template method before each test method is run.
     */
    protected function setUp()
    {
        $this->truncateTables(
            [
                'article'
            ]
        );

        self::$Article = new Article(self::$PDO);
    }

    public function testFetchRow()
    {
        self::$Article->createRow(
            [
                ':title' => 'Hello World',
                ':description' => 'Hello World',
                ':content' => 'Hello World'
            ]
        );

        $result = self::$Article->fetchRow(
            [
                ':article_id' => …
Run Code Online (Sandbox Code Playgroud)

phpunit php-5.6

6
推荐指数
1
解决办法
6977
查看次数

PHPUnit - 断言两个字符串相等失败

我有一个单元测试,我试图测试NumberFormatter.

\n\n

我的代码的简化版本是:

\n\n
public function testGetFormattedPrice()\n{\n    $formatter = NumberFormatter::create(\n        "de_DE",\n        NumbererFormatter::CURRENCY\n    );\n\n    $this->assertEquals(\n        \'16,66 \xe2\x82\xac\',\n        $formatter->formatCurrency(16.66, "EUR")\n    );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这会导致失败:

\n\n
Failed asserting that two strings are equal.\n--- Expected\n+++ Actual\n@@ @@\n-\'16,66 \xe2\x82\xac\'\n+\'16,66 \xe2\x82\xac\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我假设这与欧元符号(可能是字符编码)或字符串中的某种隐藏字节有关,但不太确定如何检查这一点?

\n\n

谁能给我一些关于如何调试这个问题的建议,或者可能的原因是什么?

\n\n

干杯,

\n\n

\n

php phpunit unit-testing

6
推荐指数
1
解决办法
9084
查看次数

Laravel phpunit 如何使用不同的迁移进行测试

我正在尝试在 Laravel 中设置测试,但我想运行与通常运行的迁移不同的迁移。

我运行的用于启动数据库的迁移从生产环境导入数据。
为了进行测试,我想使用一个名为“test”的不同数据库,并且我想用测试数据而不是生产数据填充此测试数据库。

我添加了一个config/database.php使用“测试”数据库的“测试”连接:

'connections' => [

        'mysql' => [
            'database' => env('DB_DATABASE', 'forge'),
            ...
        ],

        'testing' => [
            'database' => 'test',
            ...
        ],
],
Run Code Online (Sandbox Code Playgroud)

我设置phpunit.xml使用这个“测试”连接:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit ...>
    ...
    <php>
        <env name="DB_CONNECTION" value="testing"/>
        ...
    </php>
</phpunit>
Run Code Online (Sandbox Code Playgroud)

现在我想使用测试数据初始化这个“测试”数据库,使用来自与默认文件夹不同的文件夹的迁移。

我可以像这样使用正常的迁移:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

abstract class TestCase extends BaseTestCase
{
    use DatabaseMigrations;

    public function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }
}
Run Code Online (Sandbox Code Playgroud)

但这使用默认文件夹database/migrations。我想将测试迁移放在文件夹中tests/database/migrations

有没有办法让use …

php phpunit database-migration laravel

6
推荐指数
1
解决办法
6484
查看次数

Laravel 事件调度断言失败

我正在编写一些单元测试来测试数据库事务中间件,出现异常时事务中的所有内容都应该回滚。这段代码工作得很好并且通过了单元测试:

成功的单元测试方法

public function testTransactionShouldRollback()
{
    Event::fake();

    // Ignore the exception so the test itself can continue.
    $this->expectException('Exception');

    $this->middleware->handle($this->request, function () {
        throw new Exception('Transaction should fail');
    });

    Event::assertDispatched(TransactionRolledBack::class);
}
Run Code Online (Sandbox Code Playgroud)

然而,每当我测试一个TransactionBeginning事件时,它都无法断言该事件已被调度。

失败的单元测试方法

public function testTransactionShouldBegin()
{
    Event::fake();

    $this->middleware->handle($this->request, function () {
        return $this->response;
    });

    Event::assertDispatched(TransactionBeginning::class);
}
Run Code Online (Sandbox Code Playgroud)

实际的中间件

public function handle($request, Closure $next)
{
    DB::beginTransaction();

    try {
        $response = $next($request);

        if ($response->exception) {
            throw $response->exception;
        }
    } catch (Throwable $e) {
        DB::rollBack();
        throw $e;
    }

    if (!$response->exception) {
        DB::commit(); …
Run Code Online (Sandbox Code Playgroud)

php phpunit laravel laravel-events laravel-6

6
推荐指数
1
解决办法
6165
查看次数

SQLite SQLSTATE[HY000]:一般错误:8 尝试写入只读数据库

我正在使用 SQLite 连接和学说迁移对 PHPUnit 进行功能测试。我在setUp方法中从头开始进行数据库迁移:

public function setUp()
{
    parent::setUp();
    
    @unlink(__DIR__ . '/../../../../../../../var/sqlite.db');

    exec('./vendor/bin/doctrine-migrations migrations:migrate --db-configuration=migrations-db-test.php --configuration=migrations_test.yml --no-interaction');
}
Run Code Online (Sandbox Code Playgroud)

然后我可以从数据库写入/读取。例如:

public function test_add_event_should_add_event()
{
    $service = $this->getAdEventComparativesUpdateService();
    $request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::USER_IP);
    $response = $service->execute($request);

    $this->assertEquals(1, $response->getTotal());
}
Run Code Online (Sandbox Code Playgroud)

它有效。即使我使用相同的参数调用两次服务,它也确实有效。在这种情况下,它只需要在第一次写入:

public function test_add_two_same_events_should_add_one_event()
{
    $service = $this->getAdEventComparativesUpdateService();
    $request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::USER_IP);
    // Call twice
    $service->execute($request);
    $response = $service->execute($request);

    $this->assertEquals(1, $response->getTotal());
}
Run Code Online (Sandbox Code Playgroud)

当我必须测试两个必须同时编写的调用时,问题就出现了:

public function test_add_two_different_events_should_add_two_events()
{
    $service = $this->getAdEventComparativesUpdateService();
    $request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::USER_IP);
    $response = $service->execute($request);

    $service = $this->getAdEventComparativesUpdateService();
    $request …
Run Code Online (Sandbox Code Playgroud)

php sqlite phpunit doctrine doctrine-migrations

6
推荐指数
1
解决办法
945
查看次数

测试以断言选择输入具有特定选项

假设我有一个名为 Dogs. 我想确保当用户访问主页时,他们可以从选择输入中选择其中一只狗。我将如何在 Laravel 中测试这个?这是我到目前为止所拥有的。

    public function a_user_can_select_a_dog()
    {
        $this->withoutExceptionHandling();

        $dogs = App\Dog::all();

        $names = $dogs->map(function ($dog) {
            return $dog->name;
        });

        $response = $this->get(route('home'))->assertSee($names);
    }
Run Code Online (Sandbox Code Playgroud)

最终进入的assertSee是我所缺少的。或者也许assertSee()不是在这里使用的正确方法。我想确保当用户进入主页时,那里有一个选择输入,其中包含由工厂创建的 5 个狗的名字。

php testing phpunit laravel

6
推荐指数
1
解决办法
258
查看次数

PHPUnit\Framework\TestCase 和 Tests\TestCase 有什么区别?

我注意到在示例测试中,这两个类是内置的。

功能测试=>use Tests\TestCase;

单元测试=>PHPUnit\Framework\TestCase;

两者有什么区别?在什么情况下您会使用其中一种?

php testing phpunit laravel

6
推荐指数
1
解决办法
897
查看次数

在 Laravel/phpunit 中保留 sqlite 数据库进行多次测试以减少所需时间

我有很多测试,运行所有测试需要很长时间 ~ 15 分钟。这主要是由于构建新的 sqlite 数据库并对其进行播种的大量测试。

我的很多测试都不会更改数据库,因此它们都可以在同一个数据库上运行,该数据库仅创建一次。但是,我不知道如何设置我的测试来像这样工作。

我在 Laravel 中使用内存中的 sqlite。

我试图阻止我的 phpunit 测试每次创建和播种数据库。

我最新的尝试是使用此处详细说明的特征:/sf/answers/4045168641/

但是,当我运行测试时,第一个测试顺利通过(因此数据库表存在),然后文件中的第二个测试失败并显示:“一般错误:1 没有这样的表:用户”。

./bin/phpunit ./tests/Auth/UserTest.php
Run Code Online (Sandbox Code Playgroud)

因此,第一次测试后数据库表已被擦除。

我尝试过重写tearDown 方法,但没有什么区别。

什么可能会擦除我的数据库?

<?php

namespace Tests\Auth;

use Tests\TestCase;
use Tests\MigrateFreshAndSeedOnce;
use App\Entity\Models\User;

class UserTest extends TestCase
{

    use MigrateFreshAndSeedOnce;

    public function testUser1()
    {
        $user = User::where('id', 1)->get()->first();
        $this->assertTrue($user->id !== null);
    }

    public function testUser2()
    {
        $user = User::where('id', 2)->get()->first();
        $this->assertTrue($user->id !== null);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是特点:

<?php

namespace Tests;

use Illuminate\Support\Facades\Artisan;

trait MigrateFreshAndSeedOnce
{

    /**
     * If true, setup has …
Run Code Online (Sandbox Code Playgroud)

php sqlite phpunit laravel

6
推荐指数
1
解决办法
1314
查看次数