Add a ScannerTests project for integration tests against real scanners

This commit is contained in:
Ben Olden-Cooligan 2022-07-02 18:49:13 -07:00
parent d1e86b18e3
commit b106fcb909
8 changed files with 154 additions and 0 deletions

33
NAPS2.Sdk.ScannerTests/.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
Thumbs.db
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.sln.docstates
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
*.vssscc
$tf*/
publish/
bin/
temp/
*.credentials.json

View File

@ -0,0 +1,11 @@
namespace NAPS2.Sdk.ScannerTests;
public class HowToRunScannerTests
{
// 1. Print out the NAPS2 test page (naps2_test_page.pdf) and put it in your scanner.
// 2. Set to "" to use the first scanner device, otherwise a substring of the scanner name (e.g. "Canon").
public const string SCANNER_NAME = "";
// 3. Start debugging the test you want to run.
}

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net462</TargetFramework>
<RootNamespace>NAPS2.Sdk.ScannerTests</RootNamespace>
</PropertyGroup>
<Import Project="..\NAPS2.Setup\CommonTargets.targets" />
<Import Project="..\NAPS2.Setup\NativeLibs.targets" />
<Import Project="..\NAPS2.Setup\SdkUsers.targets" />
<ItemGroup>
<ProjectReference Include="..\NAPS2.Sdk.Tests\NAPS2.Sdk.Tests.csproj" />
<PackageReference Include="NAPS2.Wia" Version="1.0.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,14 @@
using Xunit;
namespace NAPS2.Sdk.ScannerTests;
public sealed class ScannerFactAttribute : FactAttribute
{
public ScannerFactAttribute()
{
if (!Debugger.IsAttached)
{
Skip = "Scanner tests can only run when debugging as they require user interaction.";
}
}
}

View File

@ -0,0 +1,58 @@
using NAPS2.Images.Gdi;
using NAPS2.Scan;
using Xunit;
namespace NAPS2.Sdk.ScannerTests;
public class ScannerTests
{
// TODO: Make real tests for WIA/TWAIN, Flatbed/Feeder, Color/Gray/BW, DPIs, etc.
[ScannerFact]
public async Task Test1()
{
var imageContext = new GdiImageContext();
using var scanningContext = new ScanningContext(imageContext);
var scanController = new ScanController(scanningContext);
var devices = await scanController.GetDeviceList();
var device = GetUserDevice(devices);
var options = new ScanOptions
{
Device = device,
Driver = Driver.Wia,
PaperSource = PaperSource.Flatbed,
Dpi = 100
};
var source = scanController.Scan(options);
var image = await source.Next();
Assert.NotNull(image);
using var rendered = imageContext.Render(image);
// TODO: Aside from generating the relevant files/resources, we also need to consider how to compare images when ImageAsserts assumes perfect pixel alignment.
// TODO: One possibility is having a section of the test page with gradual gradients and only compare that subsection of the images.
// ImageAsserts.Similar(ScannerTestResources.naps2_test_page, rendered);
}
// TODO: Generalize the common infrastructure into helper classes (ScannerTests as a base class, FlatbedTests, FeederTests, etc.?)
private static ScanDevice GetUserDevice(List<ScanDevice> devices)
{
if (devices.Count == 0)
{
throw new InvalidOperationException("No scanner available");
}
foreach (var device in devices)
{
if (device.Name!.IndexOf(HowToRunScannerTests.SCANNER_NAME, StringComparison.OrdinalIgnoreCase) != -1)
{
return device;
}
}
throw new InvalidOperationException("Set SCANNER_NAME to one of: " +
string.Join(",", devices.Select(x => x.Name)));
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"parallelizeTestCollections": false
}

View File

@ -1,5 +1,6 @@
namespace NAPS2.Scan;
// TODO: Can we make this a record and/or make properties non-nullable?
/// <summary>
/// The representation of a scanning device identified by a driver.
/// </summary>

View File

@ -55,6 +55,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NAPS2.Images.Gdi", "NAPS2.I
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NAPS2.App.Tests", "NAPS2.App.Tests\NAPS2.App.Tests.csproj", "{3CA45B6B-F055-4FFB-B9B6-0FF381A752F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NAPS2.Sdk.ScannerTests", "NAPS2.Sdk.ScannerTests\NAPS2.Sdk.ScannerTests.csproj", "{D291C9E9-42D2-4601-9EE3-1CBCA200B897}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -253,6 +255,16 @@ Global
{3CA45B6B-F055-4FFB-B9B6-0FF381A752F9}.InstallerMSI|Any CPU.Build.0 = Debug|Any CPU
{3CA45B6B-F055-4FFB-B9B6-0FF381A752F9}.Standalone|Any CPU.ActiveCfg = Debug|Any CPU
{3CA45B6B-F055-4FFB-B9B6-0FF381A752F9}.Standalone|Any CPU.Build.0 = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.DebugLang|Any CPU.ActiveCfg = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.DebugLang|Any CPU.Build.0 = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.InstallerEXE|Any CPU.ActiveCfg = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.InstallerEXE|Any CPU.Build.0 = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.InstallerMSI|Any CPU.ActiveCfg = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.InstallerMSI|Any CPU.Build.0 = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.Standalone|Any CPU.ActiveCfg = Debug|Any CPU
{D291C9E9-42D2-4601-9EE3-1CBCA200B897}.Standalone|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE