我们使用 DatabaseTransactions 特征和 MySQL 数据库连接执行单元测试(很多)。
当执行完整的测试套件时,我们得到 15 条左右的“常规错误:1205 超出锁定等待超时;”。当单独执行这些测试时,它们都成功了。
问题主要出现在执行sync()方法时,但不仅限于此。
(尝试增加等待超时,但没有成功)。
任何建议将不胜感激。
也发布在 laracasts 中:https://laracasts.com/discuss/channels/testing/test-suite-general-error-1205-lock-wait-timeout-exceeded
我正在 Laravel 应用程序中测试端点。但是,我有一个中间件,它执行复杂的逻辑来确定用户的位置(使用 ip 反向查找等,例如以下代码:
public function getOpCityByIP()
{
// Get the client's remote ip address
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
$clientIpAddress = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
} else {
$clientIpAddress = $_SERVER['REMOTE_ADDR'];
}
$opCityArray = OpCityIP::get($clientIpAddress);
return $opCityArray;
}
Run Code Online (Sandbox Code Playgroud)
我对深入所述中间件中此类方法的内部并不得不模拟它们等不感兴趣。我宁愿在单元测试期间简单地跳过整个中间件,或者至少模拟其整个操作,并将结果硬编码为预定的东西。我怎么做?
我正在使用 Laravel 5.4
我需要它忽略特定的中间件,而不是全部
正如 Laravel 官方文档所述,我执行了以下命令:
namespace App\Console\Commands;
use App\Model\Report;
use Illuminate\Console\Command;
use Exception;
class ExportAnualReport extends Command
{
/**
* @var string
*/
protected $description = "Print Anual Report";
/**
* @var string
*/
protected $signature = "report:anual";
public function __construct()
{
parent::__construct();
}
public function handle(Report $report): int
{
//@todo Implement Upload
try {
$reportData = $report->getAnualReport();
$this->table($reportData['headers'], $reportData['data']);
return 0;
} catch (Exception $e) {
$this->error($e->getMessage());
return 1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我已经遵循了 Laravel 的方法和建议,而不是这个问题中使用的方法 ,并且利用依赖注入来将我的模型作为服务插入。
所以我同时认为对它进行单元测试是一个好主意: …
一切......我的主题说明了一切。我正在尝试进行一个测试,实际上故意使“为 foreach() 提供的参数无效”发生。我试图让 PHPUnit 期待它,但是......不,我的测试仍然突然停止。原因是:“为 foreach() 提供的参数无效”,就在我告诉它它将发生的确切位置。
在我的文件顶部有:
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Error\Error;
use PHPUnit\Framework\Error\Notice;
use PHPUnit\Framework\Error\Warning;
Run Code Online (Sandbox Code Playgroud)
我的班级声明开头为:
Class flirzelkwerpTest extends TestCase {
Run Code Online (Sandbox Code Playgroud)
以下是测试文件中的行:
// Let's try to add nothing.
// (It should throw an error because of "Invalid argument supplied for foreach()" in barabajagal.php.)
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid argument supplied for foreach()');
$resp = $barabajagal->add();
Run Code Online (Sandbox Code Playgroud)
错误发生在最后一行。前两行不应该告诉 PHPUnit,“嘿,小伙子,我预计这里会出现错误,这是您应该逐字得到的消息”?
我们使用 PHP 7.3.4 和 PHPUnit 8.3.2。
我正在表单提交中实施新的自定义验证规则。但我想绕过单元测试中的验证规则。下面是验证规则和单元测试类的简化。我缺少什么?
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Captcha implements Rule
{
public function passes($attribute, $value)
{
// assuming will always return false in testing
// works fine when true
return false;
}
public function message()
{
return 'Captcha error! Try again later or contact site admin.';
}
}
Run Code Online (Sandbox Code Playgroud)
use Tests\TestCase;
use App\Rules\Captcha;
class RegistrationTest extends TestCase {
public test_user_registration()
{
$this->mock(Captcha::class, function ($mock) {
$mock->shouldReceive('passes')->andReturn(true);
});
$response = $this->post(route('tenant.register'), [
'g-recaptcha-response' => 1,
'email' => 'user@example.com',
'password' => 'secret',
]);
$this->assertEquals(1, …Run Code Online (Sandbox Code Playgroud) 我有这个测试:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Services\AccessTokenService;
use App\Services\MemberService;
class BranchTest extends TestCase
public function testPostBranchWithoutErrors()
{
$this->mock(AccessTokenService::class, function ($mock) {
$mock->shouldReceive('introspectToken')->andReturn('introspection OK');
});
$this->mock(MemberService::class, function ($mock) {
$mock->shouldReceive('getMemberRolesFromLdap')->andReturn(self::MOCKED_ROLES);
});
Run Code Online (Sandbox Code Playgroud)
如您所见,此测试有 2 个模拟。第二个“MemberService:class”是我当前的问题。此类中有 2 个函数:“createMember”和“getMemberRolesFromLdap”。我精确地说,我只想模拟“getMemberRolesFromLdap”函数。
在文档中,写道:
当你只需要模拟一个对象的几个方法时,可以使用partialMock方法。未被mock的方法在调用时会正常执行:
$this->partialMock(Service::class, function ($mock) { $mock->shouldReceive('process')->once(); });
但是当我使用“partialMock”时,出现以下错误:
错误:调用未定义的方法 Tests\Feature\BranchTest::partialMock()
当我尝试经典模拟(无部分)时,出现以下错误:
收到 Mockery_1_App_Services_MemberService::createMember(),但未指定期望
当然是因为这个类中有 2 个函数,所以 PhpUnit 不知道如何处理函数“createMember”。
接下来我可以尝试什么?我是 PhpUnit 测试的初学者。
Laravel 6.0
PHPUnit 7.5
我目前正在开发 Laravel CRUD 应用程序,我想知道为什么 PHPUnit 不支持抓取浏览器(正如我所读到的)。我已经通过 PHPUnit 覆盖了我的项目的基础,但我也想测试链接、标签、按钮点击等。所以我已经有了一个强大的单元测试基础。
现在我读到 Dusk 为 DOM 测试提供了一个爬虫。我应该一起使用两者吗(甚至可能吗?)还是应该迁移到 Dusk?我不确定 Dusk 是否提供与 PHPUnit 相同的功能,并且如上所述,我确实已经拥有强大的 phpunit 测试基础。
从现在开始,由于 50:50 的测试用例,我有点陷入困境,因为我还需要测试 DOM 是否提供了正确的信息。
感谢任何帮助或专家建议。
先感谢您!
在我的测试中,我使用assertSee()。
$message = '<h1>Header</h1>';
$response = $this->get($url);
$response->assertStatus(200);
$response->assertSee($message);
Run Code Online (Sandbox Code Playgroud)
问题是,当$message包含 html 实体时,断言将变为 false。
我知道有一个e()帮助程序可以在 $message 中转换 html 实体,但现在我需要相反的。
我该怎么做?
不久前,我开始在 PHPUnit (v. 9) 中编写测试。这很棒而且令人惊奇,但是:
如何正确涵盖条件语句?
我将给出一些例子,其中结果是正确的和预期的,以及我发现问题的地方。这里是:
请注意,下面的代码只是示例。
我知道当我传递
true到if语句时,将没有机会转到代码的其他分支。这只是尽可能简单的示例。
问题不存在的情况:
if (true) {
return 'true';//here is covered
}
return 'false';//here is not covered
Run Code Online (Sandbox Code Playgroud)
这没关系,但是如下:
return (true) ? 'true' : 'false';
Run Code Online (Sandbox Code Playgroud)
整行被视为覆盖,但显然 false 永远不会返回。
所以。我做什么坏事了?
唯一的解决方案是不使用三元运算符?它的语法非常短,但由于缺乏有关覆盖率的(真实/错误)信息而容易出错。:(
我正在使用Pest库在 laravel 中编写测试。我my-laravel-application/tests/Integration在 laravel 中创建了目录并在中定义了一个新的测试套件phpunit.xml
<testsuite name="Integration">
<directory suffix=".test.php">./tests/Integration</directory>
</testsuite>
Run Code Online (Sandbox Code Playgroud)
这样 Laravel 就会承认 Integration 目录中的测试文件,并且我可以在具有正确名称的单独目录(Integration 目录)中编写集成测试,并且我将测试文件放入该目录中my-laravel-application/tests/Integration,在运行时出现以下错误php artisan test:
InvalidArgumentException - Unknown format "name"
vendor/fakerphp/faker/src/Faker/Generator.php:657
Run Code Online (Sandbox Code Playgroud)
这表明$this->faker->name()我的代码行UserFactory(我在测试中使用 UserFactory 类)有问题,它说 $this->faker 上不存在 name() 方法。但在将它们移动到目录之前,我的测试曾经运行良好my-laravel-application/tests/Integration。真正的问题是什么?我该如何解决这个问题?
phpunit ×10
laravel ×6
php ×3
laravel-5 ×2
mockery ×2
command ×1
crud ×1
laravel-5.7 ×1
laravel-7 ×1
laravel-dusk ×1
mysql ×1
pestphp ×1
transactions ×1
xdebug ×1