我有一个在 Android Studio 上构建的框架,它使用 java、TestNG、appium、gradle 等。
每当我运行一个应该运行测试的任务时,构建都会成功,但测试实际上并未执行。甚至 gradle 报告也更新了。我还使用 Android 模拟器来运行测试。
我的项目是Android项目而不是Java项目。
这是项目结构:
project-root
│
├── .gradle
├── .idea
├── app
│ ├── apk
│ ├── build
│ ├── reports
│ ├── screenshots
│ └── src
│ ├── main
│ │ ├── java
│ │ │ ├── com
│ │ │ │ ├── utils
│ │ │ │ │ └── (some classes)
│ │ │ │ └── instagrid
│ │ │ │ └── application
│ │ │ │ └── (some classes - test steps)
│ │ │ └── res
│ │ └── test
│ │ ├── java
│ │ │ └── regression
│ │ │ ├── (your test classes)
│ │ │ └── regression.xml
│ │ └── res
├── gradle
└── (other project files)
这是我的回归.xml:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="instagrid" preserve-order="true">
<test name="Regression">
<classes>
<class name="regression.LandingPageTests"/>
<class name="regression.RegistrationTests"/>
<class name="regression.LoginTests"/>
<class name="regression.ProfileTests"/>
<class name="regression.BatteryDetailsTests"/>
<class name="regression.MapTests"/>
<class name="regression.TranslationsTests"/>
<class name="regression.HomePageTests"/>
<!--<class name="regression.PairingTests"/>-->
</classes>
</test>
</suite>
这是我的build.gradle:
plugins {
id 'com.android.application'
}
apply from: "testsetup.gradle"
android {
namespace 'com.example.instagrid'
compileSdk 33
defaultConfig {
applicationId "com.example.instagrid"
minSdk 33
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main.java.srcDirs = ['src/main/java']
main.resources.srcDirs = ['src/main/res']
test.java.srcDirs = ['src/test/java']
test.resources.srcDirs = ['src/test/res']
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'io.appium:java-client:7.3.0'
implementation 'org.testng:testng:7.4.0'
testImplementation project(path: ':app')
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// Other dependencies
implementation 'org.jsoup:jsoup:1.16.1'
}
task smokeTests(type: Test) {
useTestNG() {
useDefaultListeners = true
includeGroups 'smoke'
}
filter {
includeTestsMatching 'regression.xml'
}
}
这是我的testsetup.gradle:
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
ext {
env = 'uat'
defaultTestPackage = "regression"
}
tasks.withType(Test) {
classpath += files (
android.sourceSets.main.java.srcDirs,
android.sourceSets.test.java.srcDirs
)
useTestNG() {
includeGroups project.hasProperty("groups") ? "$groups" : "none"
}
testLogging {
showStandardStreams = true
events = [TestLogEvent.STARTED,
TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_OUT,
TestLogEvent.STANDARD_ERROR]
exceptionFormat = TestExceptionFormat.FULL
showCauses = true
showExceptions = true
showStackTraces = true
showStandardStreams = true
afterTest { desc, result ->
println "\nTest executed ${desc.name} [${desc.className}] with result: ${result.resultType}"
}
afterSuite { desc, result ->
if (!desc.parent) { // will match the outermost suite
def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
def startItem = '| ', endItem = ' |'
def repeatLength = startItem.length() + output.length() + endItem.length()
println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
}
}
}
enableAssertions = true
scanForTestClasses = false
options {
systemProperties(System.getProperties())
systemProperty 'env', System.properties['env'] ?: "${env}"
}
}
def generateTestRunArgs() {
def resultDir = "$projectDir/app/reports"
def suiteDir = "$projectDir/src/test/java/regression"
def regressionXML = "$projectDir/src/test/java/regression.xml"
def args = ["-d", resultDir, "-configfailurepolicy", "continue", regressionXML]
if (project.hasProperty("defaultListeners")) {
args += ["-usedefaultlisteners", "true"]
} else {
args += ["-usedefaultlisteners", "false",
"-listener", "testng.listeners.TestExecListener"]
}
if (project.hasProperty("groups")) {
args += ["-groups", "$groups"]
}
if (project.hasProperty("testclasses")) {
args += ["-testclass", "$testclasses"]
}
if (project.hasProperty("testmethods")) {
args += ["-methods", "$testmethods"]
}
if (project.hasProperty("parallel")) {
args += ["-parallel", "$parallel"]
} else {
args += ["-parallel", "methods"]
}
if (project.hasProperty("threads")) {
args += ["-threadcount", "$threads"]
args += ["-suitethreadpoolsize", "$threads"]
} else {
args += ["-threadcount", "1"]
args += ["-suitethreadpoolsize", "1"]
}
if (project.hasProperty("dataproviderthreads")) {
args += ["-dataproviderthreadcount", "$dataproviderthreads"]
} else {
args += ["-dataproviderthreadcount", "1"]
}
return args
}
/**
* Using the default gradle test task (limited options)
* Usage:
* $ gradle clean testRun --tests FeatureATest
*/
task testRun(type: Test) {
dependsOn "clean"
classpath += files(
android.sourceSets.main.java.srcDirs,
android.sourceSets.test.java.srcDirs
)
scanForTestClasses = true
forkEvery = 1
useTestNG() {
useDefaultListeners = true
includeGroups 'smoke'
}
testClassesDirs = files("src/test/java/regression")
doLast {
def args = generateTestRunArgs()
println "TestNG args: " + args
println "System property env value: ${System.properties.env}"
println "env default: $env"
}
}
/**
* Using the default gradle test task (limited options)
* Usage:
* $ gradle testGroups -Pgroups=main
* $ gradle testGroups -Pgroups=main,unit
*/
task testGroups(type: Test) {
dependsOn "clean", "classes", "testClasses"
useTestNG() {
includeGroups project.hasProperty("groups") ? "$groups" : "none"
}
testLogging.events "passed", "skipped", "failed"
testLogging.showStandardStreams = true
testLogging.exceptionFormat = "full"
}
结果:
./gradlew clean testRun -Pgroups=smoke
> Task :app:testRun
--------------------------------------------------------------------
| Results: SUCCESS (0 tests, 0 successes, 0 failures, 0 skipped) |
--------------------------------------------------------------------
TestNG args: [-d, D:\Workspace\instagrid\app/app/reports, -configfailurepolicy, continue, D:\Workspace\instagrid\app/src/test/java/regression.xml, -usedefaultlisteners, false, -listener, testng.listeners.TestExecListener, -groups, s
moke, -parallel, methods, -threadcount, 1, -suitethreadpoolsize, 1, -dataproviderthreadcount, 1]
System property env value: null
env default: uat
如果您需要更多详细信息,请告诉我。我非常想让它发挥作用,我确实尝试了一切,甚至 ChatGPT 也很困惑......
尝试使用我创建的任务运行测试,但测试并未实际执行。构建成功。
尝试使用系统属性传递值:
useTestNG() {
includeGroups System.getProperty("groups", "none")
}
现在这样称呼 lokks:
./gradlew clean testRun -Dgroups=smoke
。
-D
代替-P
!scanForTestClasses = false
已在 testRun
任务中正确覆盖。