无法从 NUnit 测试中获取 index.html
Cannot get index.html from a NUnit test
我尝试使用 NUnit 和 Asp.net-core-hosted Blazor WebAssembly 应用程序编写端到端测试。
我使用 3.1.7 模板创建了一个新项目。
然后我只是添加一个NUnit项目并编写简单的测试。
private const string serviceUrl = "https://localhost:50200";
private HttpClient _httpClient;
[OneTimeSetUp]
public void Init()
{
var arguments = new string[0];
var builder = Program.CreateHostBuilder(arguments);
_httpClient = new HttpClient();
builder
.ConfigureWebHostDefaults(w => w.UseUrls(serviceUrl))
.Build()
.Start();
}
[Test]
public async Task HomePageResponcesOk()
{
var requestUrl = serviceUrl;
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
[Test]
public async Task ApiResponcesOk()
{
var requestUrl = $"{serviceUrl}/WeatherForecast";
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
我没有改变其他任何东西。
我得到下一个结果
Test Duration Error Message
HomePageResponcesOk Failed 45 ms Expected: OK But was: NotFound
ApiResponcesOk Passed 364 ms
我做错了什么?
我可以指出,它在更早的 Blazor WebAssembly 版本中运行良好。
我还添加了另外两个测试
[Test]
public async Task AppCssResponcesOk()
{
var requestUrl = $"{serviceUrl}/css/app.css";
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
[Test]
public async Task WebAssemblyResponcesOk()
{
var requestUrl = $"{serviceUrl}/_framework/blazor.webassembly.js";
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
他们return结果相同Failed 45 ms Expected: OK But was: NotFound
。
我假设 app.UseStaticFiles();
没有像我期望的那样工作。这可能是真的吗?如何解决?
因此,当测试项目启动时,后端不知道wwwroot在哪里。可以用 UseWebRoot()
.
修复
builder
.ConfigureWebHostDefaults(w =>
{
w.UseUrls(serviceUrl);
w.UseWebRoot(@"..\..\..\..\BlazorApp2\Client\wwwroot");
})
.Build()
.Start();
除 WebAssemblyResponcesOk()
外,所有测试均已成功通过。这是因为文件放在另一个目录\BlazorApp2\Client\bin\Debug\netstandard2.1\wwwroot\_framework
。
如果我添加第二个 .UseWebRoot()
,那么只有第一个被取消。
好的,我使用调试器深入 ASP.Net 核心源代码。
还有下一个事实。
如果 运行 后端项目,则 class StaticFileMiddleware
中的 _fileProvider
字段将获得具有下一个结构的复杂值:
CompositeFileProvider-- ._fileProviders
|
+-- NullFileProvider
|
+-- StaticWebAssetsFileProvider-- .InnerProvider
|
PhysicalFileProvider
|
+-- StaticWebAssetsFileProvider-- .InnerProvider
|
PhysicalFileProvider
一个PhysicalFileProvider
指向源代码中的wwwroot,另一个指向/bin
中的wwwroot .
如果 运行 测试,StaticFileMiddleware
_fileProvider
得到简单的 PhysicalFileProvider
目标,因为 UseWebRoot()
参数是。如果我 return 到没有 UseWebRoot()
的版本,NullFileProvider
将在那里设置。
现在我可以意识到开始时发生了什么。但我仍然不知道究竟是什么对 StaticFileMiddleware 文件提供程序产生了影响。 class 构造器通过注入 IOptions<StaticFileOptions>
.
获取值
捕获这种类型的DI注册应该在哪里设置断点?
根据您收到的回复,即 “NotFound”,我的第一个猜测是为获取该特定文件而创建的路径可能不正确。如果我要调试它,我可能会尝试重载 “MapFallbackToFile” 函数。需要显式路径(绝对或相对)或其他属性的路径。经过一些尝试和尝试,您也许可以找到相应的文件。
另一件可以加快调试过程的事情是,您可以通过编程方式检查当前工作目录,并将其用作构建所需的准确文件路径的参考点。这可以使用以下命令完成:
System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
一个非常常见的错误是我们的程序通常在构建目录中 运行(例如 bin/debug/..)和我们所需的文件(例如 css 或图像)那里没有文件,因此,我们遇到了这样的问题。这是解决此问题的一种方法。
我已将 *.StaticWebAssets.xml 个文件从 ...\Server\bin\Debug\netcoreapp3.1
复制到 ...\NUnitTestProject1\bin\Debug\netcoreapp3.1
我已将 UseStaticWebAssets()
添加到后端启动代码中。
builder
.ConfigureWebHostDefaults(w =>
{
w.UseUrls(serviceUrl);
w.UseStaticWebAssets();
})
.Build()
.Start();
所有测试都通过了。调试器显示 CompositeFileProvider
注入,其结构与后端手动启动时的结构相同...
我已经在构建事件中设置了这些文件的复制
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy ..\Rest\bin$(ConfigurationName)\net5.0-windows\*.StaticWebAssets.xml .\bin$(ConfigurationName)\net5.0-windows\*.*" />
</Target>
很遗憾,我无法在测试项目中实现自动生成StaticWebAssets.xml。
我尝试使用 NUnit 和 Asp.net-core-hosted Blazor WebAssembly 应用程序编写端到端测试。
我使用 3.1.7 模板创建了一个新项目。 然后我只是添加一个NUnit项目并编写简单的测试。
private const string serviceUrl = "https://localhost:50200";
private HttpClient _httpClient;
[OneTimeSetUp]
public void Init()
{
var arguments = new string[0];
var builder = Program.CreateHostBuilder(arguments);
_httpClient = new HttpClient();
builder
.ConfigureWebHostDefaults(w => w.UseUrls(serviceUrl))
.Build()
.Start();
}
[Test]
public async Task HomePageResponcesOk()
{
var requestUrl = serviceUrl;
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
[Test]
public async Task ApiResponcesOk()
{
var requestUrl = $"{serviceUrl}/WeatherForecast";
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
我没有改变其他任何东西。
我得到下一个结果
Test Duration Error Message
HomePageResponcesOk Failed 45 ms Expected: OK But was: NotFound
ApiResponcesOk Passed 364 ms
我做错了什么?
我可以指出,它在更早的 Blazor WebAssembly 版本中运行良好。
我还添加了另外两个测试
[Test]
public async Task AppCssResponcesOk()
{
var requestUrl = $"{serviceUrl}/css/app.css";
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
[Test]
public async Task WebAssemblyResponcesOk()
{
var requestUrl = $"{serviceUrl}/_framework/blazor.webassembly.js";
var response = await _httpClient.GetAsync(requestUrl);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
他们return结果相同Failed 45 ms Expected: OK But was: NotFound
。
我假设 app.UseStaticFiles();
没有像我期望的那样工作。这可能是真的吗?如何解决?
因此,当测试项目启动时,后端不知道wwwroot在哪里。可以用 UseWebRoot()
.
builder
.ConfigureWebHostDefaults(w =>
{
w.UseUrls(serviceUrl);
w.UseWebRoot(@"..\..\..\..\BlazorApp2\Client\wwwroot");
})
.Build()
.Start();
除 WebAssemblyResponcesOk()
外,所有测试均已成功通过。这是因为文件放在另一个目录\BlazorApp2\Client\bin\Debug\netstandard2.1\wwwroot\_framework
。
如果我添加第二个 .UseWebRoot()
,那么只有第一个被取消。
好的,我使用调试器深入 ASP.Net 核心源代码。
还有下一个事实。
如果 运行 后端项目,则 class StaticFileMiddleware
中的 _fileProvider
字段将获得具有下一个结构的复杂值:
CompositeFileProvider-- ._fileProviders
|
+-- NullFileProvider
|
+-- StaticWebAssetsFileProvider-- .InnerProvider
|
PhysicalFileProvider
|
+-- StaticWebAssetsFileProvider-- .InnerProvider
|
PhysicalFileProvider
一个PhysicalFileProvider
指向源代码中的wwwroot,另一个指向/bin
中的wwwroot .
如果 运行 测试,StaticFileMiddleware
_fileProvider
得到简单的 PhysicalFileProvider
目标,因为 UseWebRoot()
参数是。如果我 return 到没有 UseWebRoot()
的版本,NullFileProvider
将在那里设置。
现在我可以意识到开始时发生了什么。但我仍然不知道究竟是什么对 StaticFileMiddleware 文件提供程序产生了影响。 class 构造器通过注入 IOptions<StaticFileOptions>
.
捕获这种类型的DI注册应该在哪里设置断点?
根据您收到的回复,即 “NotFound”,我的第一个猜测是为获取该特定文件而创建的路径可能不正确。如果我要调试它,我可能会尝试重载 “MapFallbackToFile” 函数。需要显式路径(绝对或相对)或其他属性的路径。经过一些尝试和尝试,您也许可以找到相应的文件。
另一件可以加快调试过程的事情是,您可以通过编程方式检查当前工作目录,并将其用作构建所需的准确文件路径的参考点。这可以使用以下命令完成:
System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
一个非常常见的错误是我们的程序通常在构建目录中 运行(例如 bin/debug/..)和我们所需的文件(例如 css 或图像)那里没有文件,因此,我们遇到了这样的问题。这是解决此问题的一种方法。
我已将 *.StaticWebAssets.xml 个文件从
...\Server\bin\Debug\netcoreapp3.1
复制到...\NUnitTestProject1\bin\Debug\netcoreapp3.1
我已将
UseStaticWebAssets()
添加到后端启动代码中。builder .ConfigureWebHostDefaults(w => { w.UseUrls(serviceUrl); w.UseStaticWebAssets(); }) .Build() .Start();
所有测试都通过了。调试器显示 CompositeFileProvider
注入,其结构与后端手动启动时的结构相同...
我已经在构建事件中设置了这些文件的复制
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy ..\Rest\bin$(ConfigurationName)\net5.0-windows\*.StaticWebAssets.xml .\bin$(ConfigurationName)\net5.0-windows\*.*" />
</Target>
很遗憾,我无法在测试项目中实现自动生成StaticWebAssets.xml。