如何使用线程进行客户端服务器应用程序的功能测试?

时间:2016-03-25 00:12:05

标签: python multithreading exception testing automated-tests

我有客户端和服务器模块,每个模块都可以通过一个函数启动。我只需要找到一种平行运行摊位的方法:

  1. 如果客户端/服务器发生异常会阻止另一个,那么测试运行器就不会卡住

  2. 如果客户端/服务器中发生异常,则会打印异常或将其传播给运行器,以便我可以看到它并使用测试套件调试客户端/服务器

  3. 出于性能原因,
  4. 最好使用线程

  5. 在线程的run方法中捕获异常时,使用简单线程的第一个暂定用以os._exit(1)结尾(这会杀死测试运行符...)编辑:使用线程包

    第二个尝试(试图避免使用os._exit())是concurrent.futures.ThreadPoolExecutor。它允许从线程中获取异常但我仍然找不到中止其他线程的方法。

    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        server_future = executor.submit(server)
        client_future = executor.submit(client)
    
        concurrent.futures.wait([server_future, client_future],
                               return_when=concurrent.futures.FIRST_EXCEPTION)
    
        if client_future.done() && client_future.exception():
            # we can handle the client exception here
            # but how to stop the server from waiting the client?
            # also, raise is blocking
    
        if server_future.done() && server_future.exception():
            # same here
    
    • 有没有办法用线程来实现这个目标?
    • 如果没有线程,是否有一种简单的方法来测试客户端服务器应用程序? (我认为这两个首要要求足以提供可用的解决方案)

    编辑:客户端或服务器将在accept()或receive()调用上被阻止,因此我无法定期汇集一个标志决定退出。(停止线程的经典方法之一)

1 个答案:

答案 0 :(得分:1)

您可以使用threading包。请注意,虽然强制杀死线程不是一个好主意,as discussed here。似乎没有官方方法可以在Python中杀死Thread,但是您可以按照链接帖子上给出的示例之一进行操作。

现在你需要等待一个线程退出才停止另一个线程,避免你的测试运行器被卡住。您可以使用包装服务器/客户端启动的线程,让主线程等待客户端/服务器线程退出,然后再杀死另一个。

您可以像这样定义客户端/服务器线程:

# Server thread (replace 
class testServerThread (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        # Do stuff if required

    def run(self):
        try:
            startServer() # Or startClient() for your client thread
        except: Exception 
          # Print your exception here, so you can debug

然后,启动客户端和服务器线程,并等待其中一个退出。一旦其中一个不再活着,你可以杀死另一个并继续测试。

# Create and start client/server
serverThread = testServerThread ()
clientThread = testClientThread ()

serverThread.start()
clientThread.start()

# Wait at most 5 seconds for them to exit, and loop if they're still both alive
while(serverThread.is_alive() and clientThread.is_alive()):
    serverThread.join(5)
    clientThread.join(5)

# Either client or server exited. Kill the other one.
# Note: the kill function you'll have to define yourself, as said above
if(serverThread.is_alive()):
    serverThread.kill()

if(clientThread.islive()):
    clientThread.kill()

# Done! Your Test runner can continue its work

代码的核心是join()函数:

  

等到线程终止。这会阻塞调用线程,直到调用join()方法的线程终止 - 正常或通过未处理的异常 - 或者直到发生可选的超时。

因此,在我们的情况下,它将等待5秒钟的客户端和5秒钟的服务器,如果它们两个仍然活着,它将再次循环。每当其中一个退出时,循环就会停止,剩下的线程将被杀死。