在Z大型机上构建Apache Spark时,如何避免全量编译仅按需运行指定测试套件?
在Z大型机上构建Apache Spark时,如何避免全量编译仅按需运行指定测试套件?
我完全理解你在Z大型机上跑Spark测试的痛点——每次单独跑一个测试套件都要触发全量编译,耗时极长,实在太折磨人了。结合你的场景,我整理了一套实用方案,帮你跳过重复编译,直接按需运行测试:
第一步:先完成全量预编译(仅需执行一次)
首先要确保所有生产代码和测试代码都编译完成,后续跑测试就基于这次的产物,不用再重新编译。你可以用这条命令完成预编译(包含打包,确保依赖的jar包都生成到位):
mvn -e -Phive -Phive-thriftserver -Phadoop-3 -Puser-defined-protoc -DskipDefaultProtoc -DskipTests clean package
这里-DskipTests只是跳过测试运行,不会跳过测试代码的编译,刚好符合你的需求——先把所有代码编译打包好,留着后续跑测试用。
第二步:跳过编译,直接运行指定测试套件
核心是添加两个参数完全跳过编译步骤,同时用Surefire插件直接执行测试,结合-pl和-am确保依赖模块的类路径正确。
针对未运行的测试(比如JVM故障导致漏跑的)
修改你原来的命令,加上跳过编译的参数,直接调用surefire:test:
mvn -pl connector/connect/client/jvm -am -q -e -fn \ -Phive -Phive-thriftserver -Phadoop-3 -Puser-defined-protoc -DskipDefaultProtoc \ -Dmaven.compiler.skip=true -Dscala-maven-plugin.skip=true \ -DwildcardSuites=org.apache.spark.sql.test.ConnectFunSuite -Dtest=none \ surefire:test
-Dmaven.compiler.skip=true:跳过Java代码编译-Dscala-maven-plugin.skip=true:跳过Scala代码编译(Spark大量使用Scala,这一步至关重要)-Dtest=none:避免默认执行模块内所有测试,只跑你指定的wildcardSuites
针对失败/不稳定的测试(比如MLEventsSuite)
同样的逻辑,调整模块和测试套件即可:
mvn -pl mllib -am -q -e -fn \ -Phive -Phive-thriftserver -Phadoop-3 -Puser-defined-protoc -DskipDefaultProtoc \ -Dmaven.compiler.skip=true -Dscala-maven-plugin.skip=true \ -DwildcardSuites=org.apache.spark.ml.MLEventsSuite -Dtest=none \ surefire:test
解决你遇到的两个关键问题
1. 类路径缺失的问题
之前用surefire:test找不到类,大概率是因为依赖模块的编译产物没被正确加入类路径。这里的-am参数会自动包含目标模块的所有依赖模块,加上预编译时已经生成了所有模块的jar包和class文件,就能解决这个问题。如果还是有问题,可以试试:
- 确保预编译时用了
package而不是只compile,jar包的类路径更稳定 - 临时添加
-DforkCount=0让测试在Maven进程内运行(不过Spark部分测试可能需要fork,建议先小范围测试)
2. Scala测试无法运行的问题
Spark的Scala测试依赖ScalaTest框架,Surefire插件和Scala Maven插件是集成的,只要你预编译了测试代码,并且用wildcardSuites指定Scala测试类(这是Spark官方推荐的方式),就能正常运行。如果还是识别不到,可以加个参数强制指定测试类后缀:
-Dincludes=**/*Suite.class
确保Surefire能找到所有Scala测试类。
额外优化建议
- 后续跑测试绝对不要加
clean命令,否则会删除之前的编译产物,前功尽弃 - 在Jenkins里把预编译和测试步骤拆分开:预编译步骤只执行一次,所有测试步骤都复用这次的编译结果,能把总耗时从16+小时大幅压缩
- 如果某模块代码有修改,只单独编译该模块即可:
mvn -pl 目标模块 compile test-compile,不用全量编译
备注:内容来源于stack exchange,提问作者Nicholas Marion
相关产品推荐
相关产品推荐

