【问题标题】:AspectJ with JUnit tests by inpathing the main project通过引入主项目的 JUnit 测试的 AspectJ
【发布时间】:2015-03-21 02:53:52
【问题描述】:

我已经下载了一个大型项目 (Whiley),我想跟踪在项目 JUnit 测试期间执行的每个方法。

有 6 个模块,它们大多相互依赖。

我目前正在尝试使用 Eclipse AspectJ 插件让单个模块工作。

我的 aspectJ Inpath 设置

AspectJ 编织代码并在 /bin 文件夹中生成 wyc 的编译版本。

但是,当我尝试通过 CLI 运行 JUnit 测试的 .class 文件时。

用下面的语句:

java -cp "C:\Users\name\git\WhileyCompiler\lib\junit-4.11.jar";"C:\Users\name\git\WhileyCompiler\lib\*.jar";"C:\Users\name\git\WhileyCompiler\lib\hamcrest-all-1.3.jar" org.junit.runner.JUnitCore "C:\Users\name\git\Test\bin\wyc\testing\AllValidTests.class"

我得到以下信息:

我的方面文件

    pointcut traceMethods() : (execution(* *(..))&& !cflow(within(Trace)));

before(): traceMethods(){
    Signature sig = thisJoinPointStaticPart.getSignature();
    String line =""+ thisJoinPointStaticPart.getSourceLocation().getLine();
    String sourceName = thisJoinPointStaticPart.getSourceLocation().getWithinType().getCanonicalName();
    service.addMethodCall(sourceName);
    Logger.getLogger("Tracing").log(
            Level.INFO,
            "Call from "
                +  sourceName
                +" line " +
                line
                +" to " +sig.getDeclaringTypeName() + "." + sig.getName()
    );
}

【问题讨论】:

  • 首先,它说它找不到文件。您是否验证了该声明?那个地方有没有 AllValidTests.class 文件?
  • 第二,你确定这个论点吗? JUnitCore 使用编译文件的路径作为参数,这听起来有点奇怪……

标签: java junit aspectj


【解决方案1】:

注意四点:

  • 用户 Hoàng Long 是对的,您需要指定完全限定的类名,而不是 JUnit 运行器的路径。
  • 这也意味着您需要将测试类的路径添加到类路径中。
  • 在类路径中不能使用*.jar,只能使用* 作为通配符,参见this answer
  • 此外,如果您真的想使用预编译的 AspectJ 方面,还需要将 AspectJ 运行时 aspectjrt.jar 添加到您的类路径中。

这是一个如何在您的情况下运行 JUnit 的示例。我添加了换行符以使其更具可读性,所有内容都需要在一行中:

java
    -cp
        "C:\Users\name\git\WhileyCompiler\lib\junit-4.11.jar";
        "C:\Users\name\git\WhileyCompiler\lib\*";
        "C:\Users\name\git\WhileyCompiler\lib\hamcrest-all-1.3.jar";
        "C:\Users\name\git\WhileyCompiler\lib\aspectjrt.jar";
        "C:\Users\name\git\Test\bin"
    org.junit.runner.JUnitCore
        wyc.testing.AllValidTests

更新:

实际上我这周很忙,但我只是在二进制 JAR 上使用 LTW 快速尝试了一下,但 *.whiley 测试文件已解压缩。它工作得很好,我在控制台上看到了日志输出。我不得不改变你的切入点,因为当所有加载的框架类(例如来自 JUnit)也被编织时,它会导致 LTW 场景中的输出臃肿。我还稍微简化了您的方面,以便直接在System.out 上提供格式化输出,而不是所有带有时间戳的日志记录开销,因为我发现它更具可读性。

修改方面:

package de.scrum_master.aspect;

public aspect TraceAspect {
    pointcut traceMethods() :
        execution(* *(..)) && (within(whiley..*) || within(wy*..*));

    before() : traceMethods() {
        System.out.printf(
            "%40s | %s%n",
            thisJoinPoint.getSourceLocation(),
            thisJoinPoint.getSignature() 
        );
    }
}

控制台输出:

JUnit version 4.11
.                 AllValidTests.java:2729 | void wyc.testing.AllValidTests.TypeEquals_Valid_1()
                   AllValidTests.java:97 | void wyc.testing.AllValidTests.runTest(String)
                       TestUtils.java:28 | Pair wyc.testing.TestUtils.compile(String[])
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                       Pipeline.java:292 | void wycc.lang.Pipeline.register(Class)
                        Content.java:135 | Content.Filter wyfs.lang.Content.filter(String, Content.Type)
                           Trie.java:238 | Trie wyfs.util.Trie.fromString(String)
                           Trie.java:193 | Trie wyfs.util.Trie.append(String)
                           Trie.java:312 | int wyfs.util.Trie.binarySearch(Trie[], int, String)
                        Content.java:135 | Content.Filter wyfs.lang.Content.filter(String, Content.Type)
                           Trie.java:238 | Trie wyfs.util.Trie.fromString(String)
                           Trie.java:193 | Trie wyfs.util.Trie.append(String)
                           Trie.java:312 | int wyfs.util.Trie.binarySearch(Trie[], int, String)
                        Content.java:135 | Content.Filter wyfs.lang.Content.filter(String, Content.Type)
                           Trie.java:238 | Trie wyfs.util.Trie.fromString(String)
                           Trie.java:193 | Trie wyfs.util.Trie.append(String)
                           Trie.java:312 | int wyfs.util.Trie.binarySearch(Trie[], int, String)
                     VirtualRoot.java:50 | VirtualRoot.Folder wyfs.util.VirtualRoot.root()
                     VirtualRoot.java:50 | VirtualRoot.Folder wyfs.util.VirtualRoot.root()
                     VirtualRoot.java:50 | VirtualRoot.Folder wyfs.util.VirtualRoot.root()
                        WycMain.java:179 | int wyc.WycMain.run(String[])
                         OptArg.java:322 | Map wycc.util.OptArg.parseOptions(List, OptArg[])
                         OptArg.java:218 | void wycc.util.OptArg.FILEDIR.process(String, String, Map)
                         OptArg.java:231 | void wycc.util.OptArg.FILELIST.process(String, String, Map)
                        WycMain.java:258 | void wyc.WycMain.configure(Map)
                   WycBuildTask.java:331 | void wyc.util.WycBuildTask.setVerbose(boolean)
                   WycBuildTask.java:335 | void wyc.util.WycBuildTask.setVerification(boolean)
                   WycBuildTask.java:343 | void wyc.util.WycBuildTask.setSmtVerification(boolean)
                   WycBuildTask.java:339 | void wyc.util.WycBuildTask.setVerificationConditions(boolean)
                   WycBuildTask.java:359 | void wyc.util.WycBuildTask.setWhileyDir(File)
                  DirectoryRoot.java:135 | DirectoryRoot.Folder wyfs.util.DirectoryRoot.root()
                  DirectoryRoot.java:135 | DirectoryRoot.Folder wyfs.util.DirectoryRoot.root()
                   WycBuildTask.java:399 | void wyc.util.WycBuildTask.setBootPath(List)
                                     ... | ...

【讨论】:

  • 它现在正在运行测试 A-OK 谢谢。但是,方面似乎没有被编织到它的 output.jar 文件中。我的项目文件如下所示:prntscr.com/6jtunz
  • 好吧,该屏幕截图信息不足,无法找出问题所在。一个真正的SSCCE 会更好,因为我可以重现你的情况。除此之外,我想知道为什么在这种情况下你完全使用 CTW(编译时编织)而不是 LTW(加载时编织),因为后者在(不)修改第三方库方面的侵入性微乎其微。为什么你完全自己编译它们,而不是把它们当作给定的并使用 JAR?
  • @kriegaex:非常详细和好的答案。我个人认为这个问题很难理解,因为我不明白 AspectJ 与 JUnit 有什么关系?
  • AspectJ 与 JUnit 没有任何关系,忽略了作者希望将它们一起使用以跟踪他的单元测试这一事实。 ;-)
  • 我已经用一些源代码和控制台日志更新了我的答案。
【解决方案2】:

我认为问题在于您提供给 JUnit 的参数。我们进入编译好的类所在的文件夹,运行命令:

java -cp "(classpath here)" org.junit.runner.JUnitCore wyc.testing.AllValidTests

如果我没记错的话,提供的参数必须是类名,不是编译文件的路径。

【讨论】:

  • 测试类也需要一个完全限定的包名。请参阅我自己的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多