Laravel 测试 url 到 public 目录中的资源
Laravel testing url to resource in public directory
我正在使用 Laravel Dusk 来测试页面上的所有链接,这些链接是使用 [=32= 从 resources/docs 复制到 public/docs 的 PDF 文件] 混合
问题是尝试使用 get(uri) 方法访问文档的 URL 会得到 404,这是我的 Dusk 的简化版本:
protected function refreshApplicationWithLocale($locale)
{
self::tearDown();
putenv(LaravelLocalization::ENV_ROUTE_KEY . '=' . $locale);
self::setUp();
}
protected function setUp(): void
{
parent::setUp();
if(!File::copyDirectory( resource_path('docs'), public_path() . '/docs'))
throw new \Exception("couldn't copy the folder :(");
// Storage::assertExists(public_path() . '/docs/clothing/existing_file.pdf'); // this assertion fails, what's weird is the path in the exception message does actually exist
$this->artisan('storage:link');
}
protected function tearDown(): void
{
parent::tearDown();
foreach (static::$browsers as $browser) {
$browser->driver->manage()->deleteAllCookies();
}
}
public function testClothing()
{
$this->refreshApplicationWithLocale('fr');
$this->get('/test')->assertStatus(200); // passes
$this->get('/fr/vetements')->assertStatus(200); // passes
//usually I'd get the page urls dynamically with Dusk, but for simplicity sake I'm just testing with this link that I know it exists and can curl it from withing Homestead
$this->get('/docs/clothing/Hoodies.pdf')->assertStatus(200); //failes (404)
}
我错过了什么?
谢谢。
P.S.: 我正在使用 laravel 8 和 Homestead
编辑:
在@steven7mwesigwa 回答后,这是我的最终代码:
protected function refreshApplicationWithLocale($locale)
{
self::tearDown();
putenv(LaravelLocalization::ENV_ROUTE_KEY . '=' . $locale);
self::setUp();
}
protected function setUp(): void
{
parent::setUp();
if(!File::copyDirectory( resource_path('docs'), public_path() . '/docs'))
throw new \Exception("couldn't copy the documents folder :(");
}
protected function tearDown(): void
{
parent::tearDown();
foreach (static::$browsers as $browser) {
$browser->driver->manage()->deleteAllCookies();
}
}
public function testClothing()
{
$this->refreshApplicationWithLocale('fr');
$elements = [];
$this->browse(function (Browser $browser) use(&$elements){
$elements = $browser->visit('myroute')
->elements('.tmp_products_list a', 'href');
});
$this->assertGreaterThan(1, count($elements));
foreach($elements as $element) {
$response = Http::get($element->getAttribute('href'));
self::assertEquals($response->status(), 200);
}
}
问题 1:
// Storage::assertExists(public_path() . '/docs/clothing/existing_file.pdf');
// this assertion fails, what's weird is the path in the exception message does actually exist
The Storage
facade uses the storage that is active in your config
files (config/filesystems.php
). Note that this defaults to local
.
The root path is set for each storage option. In the case of local,
it's pointing to storage/app
out of my head. - @bobbybouwmann
另外,通过storage
路径搜索的正确方法,是先指定filesystem "disk"。即,对于驻留在 storage/app/public/demo.js:
中的文件
Storage::disk("public")->assertExists("demo.js");
除此之外,由于您所需的测试文件位于 pubic 文件夹中,因此可以使用以下方法进行测试:
$this->assertFileExists(public_path() . '/docs/clothing/existing_file.pdf');
问题 2:
//usually I'd get the page urls dynamically with Dusk, but for simplicity sake I'm just testing with this link that I know it exists and can curl it from withing Homestead
$this->get('/docs/clothing/Hoodies.pdf')->assertStatus(200); //failes (404)
上面的代码片段不起作用,因为 $this->get(...)
本质上是在与此路径对应的应用程序路由文件中搜索 明确定义的路由 没有找到。
您必须使用浏览器测试框架(即 Laravel Dusk)来测试 Web 服务器上的静态文件。
可在此处找到更多内容:
尽管如此,由于您已经在使用 Laravel Dusk,这可以通过以下方式实现:
$this->browse(function (Browser $browser) {
$browser->visit('/docs/clothing/Hoodies.pdf')
->assertDontSee("404")
->assertDontSee("NOT FOUND");
});
如果 URL 有效且 PDF 文件存在并加载,则不会加载 HTML 视图。因此测试应该通过。
如果 URL 无效,将加载 Laravel 的默认 404.blade.php
视图。该视图包括以下文本字符串:“404”和“NOT FOUND”。因此在这种情况下测试会失败。
如果您已经有 custom 404,请随意更改 assertDontSee(....)
方法参数中传递的文本字符串错误页面。
我正在使用 Laravel Dusk 来测试页面上的所有链接,这些链接是使用 [=32= 从 resources/docs 复制到 public/docs 的 PDF 文件] 混合
问题是尝试使用 get(uri) 方法访问文档的 URL 会得到 404,这是我的 Dusk 的简化版本:
protected function refreshApplicationWithLocale($locale)
{
self::tearDown();
putenv(LaravelLocalization::ENV_ROUTE_KEY . '=' . $locale);
self::setUp();
}
protected function setUp(): void
{
parent::setUp();
if(!File::copyDirectory( resource_path('docs'), public_path() . '/docs'))
throw new \Exception("couldn't copy the folder :(");
// Storage::assertExists(public_path() . '/docs/clothing/existing_file.pdf'); // this assertion fails, what's weird is the path in the exception message does actually exist
$this->artisan('storage:link');
}
protected function tearDown(): void
{
parent::tearDown();
foreach (static::$browsers as $browser) {
$browser->driver->manage()->deleteAllCookies();
}
}
public function testClothing()
{
$this->refreshApplicationWithLocale('fr');
$this->get('/test')->assertStatus(200); // passes
$this->get('/fr/vetements')->assertStatus(200); // passes
//usually I'd get the page urls dynamically with Dusk, but for simplicity sake I'm just testing with this link that I know it exists and can curl it from withing Homestead
$this->get('/docs/clothing/Hoodies.pdf')->assertStatus(200); //failes (404)
}
我错过了什么?
谢谢。
P.S.: 我正在使用 laravel 8 和 Homestead
编辑:
在@steven7mwesigwa 回答后,这是我的最终代码:
protected function refreshApplicationWithLocale($locale)
{
self::tearDown();
putenv(LaravelLocalization::ENV_ROUTE_KEY . '=' . $locale);
self::setUp();
}
protected function setUp(): void
{
parent::setUp();
if(!File::copyDirectory( resource_path('docs'), public_path() . '/docs'))
throw new \Exception("couldn't copy the documents folder :(");
}
protected function tearDown(): void
{
parent::tearDown();
foreach (static::$browsers as $browser) {
$browser->driver->manage()->deleteAllCookies();
}
}
public function testClothing()
{
$this->refreshApplicationWithLocale('fr');
$elements = [];
$this->browse(function (Browser $browser) use(&$elements){
$elements = $browser->visit('myroute')
->elements('.tmp_products_list a', 'href');
});
$this->assertGreaterThan(1, count($elements));
foreach($elements as $element) {
$response = Http::get($element->getAttribute('href'));
self::assertEquals($response->status(), 200);
}
}
问题 1:
// Storage::assertExists(public_path() . '/docs/clothing/existing_file.pdf');
// this assertion fails, what's weird is the path in the exception message does actually exist
The
Storage
facade uses the storage that is active in your config files (config/filesystems.php
). Note that this defaults tolocal
. The root path is set for each storage option. In the case of local, it's pointing tostorage/app
out of my head. - @bobbybouwmann
另外,通过storage
路径搜索的正确方法,是先指定filesystem "disk"。即,对于驻留在 storage/app/public/demo.js:
Storage::disk("public")->assertExists("demo.js");
除此之外,由于您所需的测试文件位于 pubic 文件夹中,因此可以使用以下方法进行测试:
$this->assertFileExists(public_path() . '/docs/clothing/existing_file.pdf');
问题 2:
//usually I'd get the page urls dynamically with Dusk, but for simplicity sake I'm just testing with this link that I know it exists and can curl it from withing Homestead
$this->get('/docs/clothing/Hoodies.pdf')->assertStatus(200); //failes (404)
上面的代码片段不起作用,因为 $this->get(...)
本质上是在与此路径对应的应用程序路由文件中搜索 明确定义的路由 没有找到。
您必须使用浏览器测试框架(即 Laravel Dusk)来测试 Web 服务器上的静态文件。
可在此处找到更多内容:
尽管如此,由于您已经在使用 Laravel Dusk,这可以通过以下方式实现:
$this->browse(function (Browser $browser) {
$browser->visit('/docs/clothing/Hoodies.pdf')
->assertDontSee("404")
->assertDontSee("NOT FOUND");
});
如果 URL 有效且 PDF 文件存在并加载,则不会加载 HTML 视图。因此测试应该通过。
如果 URL 无效,将加载 Laravel 的默认 404.blade.php
视图。该视图包括以下文本字符串:“404”和“NOT FOUND”。因此在这种情况下测试会失败。
如果您已经有 custom 404,请随意更改 assertDontSee(....)
方法参数中传递的文本字符串错误页面。