是否有多进程单元测试框架/junit 插件?
想象一下两个服务器(每个都在自己的jvm进程中)使用某种形式的消息(例如简单的生产者/消费者)进行通信
我想编写单元测试来测试这两个服务器的行为。
我的问题是:
是否有一些框架(或 junit 插件)可以解决这个问题?
我想在不同的进程中运行 junit 测试类(甚至单个测试)? 如果一个单元测试可以使用某种进程间通信轻松访问另一个测试(在不同进程中)的变量,那就太酷了。
例如,我想检查生产者是否真的生产了我期望的东西,然后检查消费者是否消费了它们。 (也许会做一些模糊测试来检测一些与竞争条件相关的问题)这种测试有一些最佳实践吗?
如果没有类似单元的测试方法,您将如何在持续集成期间测试此类内容?
注意:
我不想使用线程,因为这可能会改变行为(如果您考虑线程安全问题)
Imagine two servers (each within an own jvm process) which communicate using some form of messages (e.g. simple producer/consumer)
I'd like to write unit tests that will test the behaviour of these two servers.
My questions are:
Are there some frameworks (or a junit addon) for this problem?
I'd like to run a junit test class (or even a single test) in a different process?
It would be cool if one unit test can easily access the variables of the other test (in a different process) using some sort of inter-process communication.
E.g. I'd like to check if the producer really produced the things i expected, and afterwards, if the consumer consumed them. (and maybe do some fuzzing to detect some race-condition-related problems)Are there some best practice for this kind of testing?
If there isn't a unit-like testing approach, how would you test such things during continous integration?
Note:
I don't want to use threads, because this may alter the behaviour (if you think of thread-safety issues)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我将描述您想要做的集成测试,并且超出了 JUnit 作为框架的范围(JUnit 现在才涉足多线程测试,多进程当然不在功能集中)。
您当然可以使用 JUnit 来运行此类测试,但它们实际上仅限于运行程序,其余的您必须自己完成。
其他人已经指出这样一个事实:您通常会模拟或以其他方式向消费者发送人工构造的方法,并在“单元测试”级别独立测试生产者生成的内容。
就实际测试生产者和消费者之间的交互而言,一种方法是忘记进程间测试,并通过某种依赖注入在一个线程上进行进程内测试,其中生产者通过某种虚假发送消息这种方式只是将其传递给消费者,除了线程内方法调用之外,没有任何其他内容。
然而,您似乎想要测试在其之上的实际进程间内容(竞争条件等)可能发生的事情,这使得这更像是一个集成测试。
要解决这个问题,您需要启动进程并等待它接受消息,然后您的测试将告诉生产者要创建什么消息,并将其发送给消费者。然后你的测试会询问消费者得到了什么(有适当的延迟)。
这里的需求必须迫使我这样做。我会进行全面的自动化验收测试,并让它包含这种级别的集成。
I would describe what you are looking to do as an integration test, and beyond the scope of JUnit as a framework (JUnit is only now dipping its toe into multi-thread testing, multi-process is certainly not in the feature set).
You could of course use JUnit to run such tests, but they would really be limited to a runner, the rest you have to do yourself.
Others have already pointed to the fact that you would usually mock or otherwise send artificially constructed methods to the consumer, and test what the producer produces independently at the "unit test" level.
In terms of actually testing the interaction between the producer and the consumer, one approach is to forget about the inter-process testing, and test it intra-process on one thread via some sort of Dependency Injection where the producer sends the message via some fake way that just passes it on the the consumer without anything more under the hood than in-thread method calls.
However, it seems that you want to test things that can happen with the actual inter-process stuff on top of it (race conditions and the like), which makes this all-the-more an integration test.
To approach this problem, you need to start the process and wait for it to accept a message, then your test would tell the producer what message to create and it would send it to the consumer. Then your test would ask the consumer what it got (with suitable delay).
The need here would have to be compelling for me to do it. I would go for full blown automated acceptance testing and let that encompass this level of integration.
您应该看看 XHarness,我相信它可以满足您的需求。我最近使用过它,它对我们当时的项目非常有效。
从其页面:
You should take a look at XHarness, which I believe meets your needs. I've used it in the recent past and it worked great for our projects at the time.
From its page:
我建议使用模拟对象,然后您可以独立测试生产者和消费者,并模拟对方。所以你测试生产者生产,消费者消费。
您还可以测试两者通信的机制,但我希望这是由第三方提供的?
请参阅 Mockito、jMock,EasyMock
I'd recommend using mock objects, you can then test the producer and the consumer independently mocking out the other. So you test the producer produces, and the consumer consumes.
You can also test the mechanism the two communicate, but I'd expect thats provided by a 3rd party?
See Mockito, jMock, EasyMock
您在第 1 点中所说的并不是真正的单元测试场景。在完美的单元测试中,您不会担心谁在生成消息以及谁在消费消息。您的测试用例之一将集中于想象(或模拟)您从有效的生产者处收到不同的消息,并且您的测试用例将测试如何正确使用这些消息。您正在寻找的更像是集成测试。无论如何,我所做的一些陈述可能是主观的。您可以使用 jMock、easymock 框架来满足您的模拟需求。
What you are talking in point 1 is not a true unit testing scenario. In a perfect unit test you will not worry about who is producing the messages and who is consuming the messages. One of your test case will concentrate on imagining(or mocking) that you received different messages from a valid producer and your test cases will test how these are being consumed properly. What you are looking is more like a integration testing. Anyway some of the statements which I made may be subjective. You can use jMock, easymock frameworks for your mocking needs.
这远远超出了单元测试的范围,并且牢牢地包含在集成测试中。
我建议通过模拟每个部分单独的通信层来测试您可以做什么。
我过去在这种情况下所做的就是在测试中启动一个单独的线程来启动模拟接收器/发送器。在主要测试中,我然后执行发送者/接收者部分。在实践中,这意味着这充满了延迟,以确保事情按正确的顺序开始,这变得非常慢,所以你只想这样做来测试拼图的各个部分是否合适,并尽可能少地进行功能测试它。
我验证所需的行为并在离开测试之前终止辅助线程。
这个可以测试很多。使用单独的进程(和主机!)进行测试确实很痛苦。需要很长时间,我会将其限制为手动测试。
This is way beyond Unit testing and firmly inside Integration testing.
I would recommend to test what you can by mocking out your comms layer with each piece separate.
What I did in the past in such cases is to start a separate thread in the test which starts a Mock Receiver/Sender. In the main test I then do the Sender/Receiver part. In practice this means this is full of delays to make sure things start in the right order and this becomes dead slow, so you just want to do this to test that the pieces of the puzzle fit, and do as little as possible functional testing over it.
I verify the desired behavior and terminate the helper thread before leaving the test.
This can test a lot. Testing using separate processes (and hosts!) is a real pain. takes forever and I would limit that to manual testing.
回答问题2和3:
关于架构,我会考虑将创建进程的责任委托给操作系统或主机。正如这个线程 从 shell 脚本执行 Maven 任务并获取错误代码,在您选择的 shell 脚本环境中使用同步机制来验证错误。即使在 CI/CD 管道中,通常也有一个在操作系统之上运行的脚本,理论上您可以对其进行修改。
To reply to questions 2 and 3:
With respect to architecture, I would consider delegating the responsibility of creating the processes to the operating system, or host. As in this thread Executing Maven task from shell script and getting error codes, use synchronization mechanisms in your shell scripting environment of your choice to verify errors. Even in CI/CD pipelines, there is usually a script running on top of the OS which you could theoretically modify.