章节目录:
使用 -help
命令行选项:
jtestcli.exe -help |
要让 Jtest 使用系统代理设置,需使用 -D
命令行选项配置 java.net.useSystemProxies=true
。
如果您的代理服务器要求进行身份验证,则可以使用 parasoft.https.systemProxyUser=[用户名]
和parasoft.https.systemProxyPassword=[密码,可由 Parasoft 加密]
属性配置您的凭据。需为每个协议分别指定用户和密码。
您的命令行可能与以下内容类似:
java -Djava.net.useSystemProxies=true -Dparasoft.https.systemProxyUser=user -Dparasoft.https.systemProxyPassword=password |
要使用手动设置通过代理服务器进行连接,需要将协议专用的系统属性传递给 JVM(使用 -D
命令行选项)来配置连接。要与 Jtest 一起使用,应确保配置 HTTPS 协议的系统属性。至少,您必须配置 https.proxySet=true
、https.proxyHost=[hostname]
和 https.proxyPort=[port number]
。如果代理服务器要求身份验证,则可以使用 https.proxyUser
和 https.proxyPassword
属性。
您的命令行可能与以下内容类似:
java -Dhttps.proxySet=true -Dhttps.proxyHost=myserver.example.com -Dhttps.proxyPort=8080 -Dhttps.proxyUser=user1 -Dhttps.proxyPassword=MyPassword |
此外,您还可以配置 https.nonProxyHosts
属性来指定不需要通过代理连接的主机。
如果您在 Eclipse 或 IntelliJ IDEA 中使用桌面版 Jtest,Jtest 能够自动检测并使用 Eclipse 或 IntelliJ IDEA 中指定的代理设置。不需要额外的配置。
注意:如果使用 java.net.useSystemProxies
属性启用了系统代理设置,则这些设置将覆盖 IDE 设置。
如果出现以下对话框:无法打开“java”,因为无法验证开发者,需按照以下步骤操作:
另请参阅 https://support.apple.com/en-us/HT202491。
网络环境的变化可能会影响用于计算机器码的接口,从而导致机器码不稳定。您可以使用 PARASOFT_SUPPORT_NET_INTERFACES 环境变量指定一个稳定的接口,防止机器码变化。
将变量值设置为稳定的以太网网络接口。请勿使用虚拟接口、临时接口或环回接口。
- Windows:将值设为网卡的 MAC 地址。您可以使用 ipconfig-all
命令获取地址。 例如:
SET PARASOFT_SUPPORT_NET_INTERFACES=00-10-D9-27-AC-85 |
- Linux:例如,将值设为“inet”或“inet6”系列中的一个网络接口。您可以使用 ifconfig
命令获取可用接口的列表。例如:
export PARASOFT_SUPPORT_NET_INTERFACES=eth1 |
如果问题仍然存在,可以通过设置环境变量 PARASOFT_DEBUG_NET_INTERFACES 并将值设置为 true 来获取诊断信息。这将在标准输出中打印可与技术支持共享的检查步骤,以及用于计算您的机器码的界面。界面将标有 [SELECTED] 前缀。
如果您是 Mac OS 用户,在执行 Jtest 时可能会遇到问题,因为 Jtest 不符合 Mac OS 常规的应用程序格式,并且在 App Store 之外下载。因此,jtestcli 和包含的 JRE 都将被系统隔离。
这是所有非 App Store 应用程序的常见问题。您可以在 Mac OS 隐私与安全性系统设置中手动允许打开每个可执行文件(请参阅 https://support.apple.com/en-us/HT202491)。要轻松移除这些文件的隔离属性,可运行 jtest_installation_folder/bin/remove_quarantine_flag.sh
脚本。
新版本的 Jtest 可能需要更多内存来运行静态分析。您可以通过在 [INSTALL_DIR]/etc/jtestcli.jvm 配置文件中配置 -Xmx 选项来增加内存分配。
如果 Jtest 报告在 Maven 测试范围中导入依赖项出现编译问题,可尝试使用 mvn test
命令运行 jtest:jtest
目标:
mvn test jtest:jtest |
默认情况下,Jtest 会将项目的编译输出路径添加到 Java 解析器所使用的 classpath 中。但在某些项目中,这可能会导致 Java 解析器报告编译错误。为解决该问题,可以尝试从 Java 解析器的 classpath 中排除编译器输出路径:
set jtest.parser.includeCompilerOutput=false |
jtest:coverage
目标(Maven)或 jtest-coverage
任务(Gradle)会导致构建失败?Jtest·coverage
目标/任务在 10.2.2 版本(插件版本 1.2.4)中已被移除,不再可用(请参阅从 10.x 迁移到 10.2.2 或更高版本)。执行此目标会导致构建失败,并显示以下消息:
[ERROR] Could not find goal 'coverage' in plugin com.parasoft.jtest:jtest-maven-plugin
. (Maven)
Task 'jtest-coverage' not found(Gradle)
当您对多模块项目使用 Jtest 执行测试影响分析时,如果某个子模块中不包含被识别的受影响测试,Gradle 构建可能会失败。为防止 Gradle 构建未找到测试时失败,应配置以下选项:setFailOnNoMatchingTests(false)
要启用覆盖率收集,Jtest 会自动为 Jtest·覆盖率代理配置 JVM 参数。覆盖这些参数会阻止 Jtest 收集覆盖率数据。如果 Gradle 构建脚本修改了 JVM 参数,应确保将它们添加(+=)到其他 JVM 参数中,以防止重写:
] |
] |
为确保正确处理和测试包含 BOM 的文件,您需要配置 Jtest 在解析文件时删除 BOM。将以下设置之一添加到 jtest.properties
配置文件中:
jtest.parser.bom=remove
- 删除 BOM,原始文件编码不变。jtest.parser.bom=recognize
- 删除 BOM 并使用 BOM 定义的编码覆盖原始编码默认情况下,Jtest 不区分在相同代码上运行时始终失败的测试和可能通过或失败的测试(不稳定测试)。 您可以通过启用已弃用的 XML 处理机制来让 Jtest 识别不稳定测试。 在 jtestcli.properties
配置文件中添加以下选项:
jtest.unittest.xml.results.processing.enabled=
true
请注意,启用已弃用的 XML 处理机制可能会影响测试执行速度。
当在 classpath 中将 mockito-inline 放在 powermock 之前运行 PowerMock 测试时,可能会出现测试失败并显示以下异常:
NotAMockException: Argument should be a mock, but is: class java.lang.Class |
这是由于 PowerMock 与 mockito-inline mock maker 的交互存在问题所导致的(详细信息,请参阅 PowerMock 问题)。
根据您的需求,有几种可行的解决方案:
关于可以被模拟的类和方法存在一些限制。详细信息,请参阅 Mockito 静态和构造函数模拟限制。
可以轻松修改以下导致问题的 PowerMock 调用:
例如:
PowerMockito.when(MyClass.staticCall(any())).thenReturn("value"); PowerMockito.when(MyClass.staticCall(any())).thenReturn("value1", "value2"); PowerMockito.doReturn("value").when(MyClass.class); MyClass.staticCall(any()); PowerMockito.doNothing().when(MyClass.class, "staticCall", any()); |
更新代码:
PowerMockito.when(MyClass.staticCall(any())).thenAnswer(invocation -> "value"); PowerMockito.when(MyClass.staticCall(any())).thenAnswer(invocation -> "value1").thenAnswer(invocation -> "value2"); PowerMockito.doAnswer(invocation -> "value").when(MyClass.class); MyClass.staticCall(any()); PowerMockito.doAnswer(invocation -> null).when(MyClass.class, "staticCall", any()); |
调用 verifyStatic() 或 verifyPrivate() 时,可能会遇到以下测试异常:
org.mockito.exceptions.misusing.NotAMockException: Argument passed to verify() is of type Class and is not a mock! Make sure you place the parenthesis correctly! See the examples of correct verifications: verify(mock).someMethod(); verify(mock, times(10)).someMethod(); verify(mock, atLeastOnce()).someMethod(); |
应该重构代码并手动验证所需的调用。
例如:
PowerMockito.when(MyClass.staticCall(any())).thenAnswer(invocation -> "value"); ... PowerMockito.verifyStatic(MyClass.class, times(1)); MyClass.staticCall(any()); |
更新代码:
int counter[] = new int[]{0}; PowerMockito.when(MyClass.staticCall(any())).thenAnswer(invocation -> { counter[0]++; return "value"; }); ... assertEquals(1, counter[0]); |
对于 verifyPrivate(),唯一的解决方案就是手动验证所需的调用,因为 Mockito 不支持模拟私有方法。
例如:
PowerMockito.mockStatic(MyClass.class); PowerMockito.when(MyClass.class, "privateStatic", any()).thenAnswer(invocation -> inv.callRealMethod()); ... PowerMockito.verifyPrivate(MyClass.class, times(1)).invoke("privateStatic"); |
更新代码:
PowerMockito.mockStatic(MyClass.class); int counter[] = new int[]{0}; PowerMockito.when(MyClass.class, "privateStatic", any()).thenAnswer(invocation -> { counter[0]++; return inv.callRealMethod(); }); ... assertEquals(1, counter[0]); |
PowerMock 代码:
PowerMockito.mockStatic(MyClass.class); PowerMockito.when(MyClass.staticCall(any())).thenReturn("value"); // test code PowerMockito.verifyStatic(MyClass.class, times(1)); MyClass.staticCall(any()); |
代码转换为 Mockito:
try (MockedStatic<FunctionsToMock> mocked = mockStatic(FunctionsToMock.class)) { mocked.when(() -> FunctionsToMock.staticCall(any())).thenReturn("value"); // test code mocked.verify(() -> FunctionsToMock.staticCall(any()), times(1)); } |
PowerMock 代码:
FunctionsToMock mock = Mockito.mock(FunctionsToMock.class); PowerMockito.whenNew(FunctionsToMock.class).withAnyArguments().thenReturn(mock); when(mock.calculate()).thenReturn(1); // test code |
代码转换为 Mockito:
try (MockedConstruction<FunctionsToMock> mocked = mockConstruction(FunctionsToMock.class, (mock, context) -> { when(mock.calculate()).thenReturn(1); })) { // test code } |
Mockito 不支持以下用例:
Mockito 也不建议静态模拟 JDK 中的任何类。
如果批量测试创建的效果不佳,这可能表明存在潜在的设置问题。
详细诊断问题的步骤:
为正确处理和分析文件,Jtest 必须要能够将您在测试范围中提供的文件名(即项目中的文件名)与源码控制系统中的文件名进行匹配。因此,如果您使用的是区分大小写的源码控制系统,例如 Git,则需要确保文件名大小写一致。
在 Windows 上,文件路径长度超过 250 个字符可能会导致该文件无法访问。如果您的工作空间嵌套在较深的文件夹层级中,某些 UTA 文件的路径可能会超过 250 个字符。无法访问测试执行所需的关键文件时,测试执行便会失败。
为确保 UTA 文件的路径不会超过限制,您可以考虑将工作空间文件夹移至文件夹层级目录中更高的层级。
在极少数情况下,由于 IntelliJ 版本中的已知问题,Jtest 运行配置可能无法生效(详细信息,请参阅 https://youtrack.jetbrains.com/issue/IDEA-223124)。如果发生这种情况,您需要重启 IDE。Jtest 运行配置将在重启后生效。
使用最新的 Ubuntu Linux(21.10 或更新版本)并将基于 Snap 的 Firefox 浏览器作为默认浏览器时,Eclipse IDE 可能无法正确显示 HTML 内容(另请参阅:https://github.com/eclipse-platform/eclipse.platform.swt/issues/221)。有以下两种解决方法:
注意:要将 Firefox 配置为“外部 web 浏览器”,应使用以下设置:
位置:/usr/bin/env
Parameters:firefox %URL%