单元测试框架:在新进程中运行测试

时间:2011-07-22 14:15:13

标签: python unit-testing multiprocessing

我编写了一个使用Unit testing framework的GUI应用程序。 该应用程序在树视图中显示所有找到的单元测试。 如果单击单元测试名称,程序将运行此测试并显示结果。 它有效!

但现在我希望每个测试用例都在一个新进程中运行。 我创建了一个“工作线程”(带有模块线程),但是这个线程也在同一个进程中运行。

模块“多处理”是解决方案,但我的实现遇到了问题。 我将“测试执行代码”放在自己的函数中并尝试:

item = self.GetSelection()
name = self.GetItemText(item)
p = multiprocessing.Process(target=ExecuteTest, args=(name, item))
p.daemon = True
p.start()

但后来我遇到了错误。

Traceback (most recent call last):
  File "C:\a\b\c\hhh\a.py", line 577, in OnLeftDClick
    p.start()
  File "C:\Python26\lib\multiprocessing\process.py", line 104, in start
    self._popen = Popen(self)
  File "C:\Python26\lib\multiprocessing\forking.py", line 239, in __init__
    dump(process_obj, to_child, HIGHEST_PROTOCOL)
  File "C:\Python26\lib\multiprocessing\forking.py", line 162, in dump
    ForkingPickler(file, protocol).dump(obj)
  File "C:\Python26\lib\pickle.py", line 224, in dump
    self.save(obj)
  File "C:\Python26\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "C:\Python26\lib\pickle.py", line 419, in save_reduce
    save(state)
  File "C:\Python26\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Python26\lib\pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "C:\Python26\lib\pickle.py", line 681, in _batch_setitems
    save(v)
  File "C:\Python26\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Python26\lib\pickle.py", line 548, in save_tuple
    save(element)
  File "C:\Python26\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "C:\Python26\lib\pickle.py", line 419, in save_reduce
    save(state)
  File "C:\Python26\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Python26\lib\pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "C:\Python26\lib\pickle.py", line 686, in _batch_setitems
    save(v)
  File "C:\Python26\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "C:\Python26\lib\pickle.py", line 396, in save_reduce
    save(cls)
  File "C:\Python26\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Python26\lib\pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <type 'PySwigObject'>: it's not found as __builtin__.PySwigObject

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python26\lib\multiprocessing\forking.py", line 342, in main
    self = load(from_parent)
  File "C:\Python26\lib\pickle.py", line 1370, in load
    return Unpickler(file).load()
  File "C:\Python26\lib\pickle.py", line 858, in load
    dispatch[key](self)
  File "C:\Python26\lib\pickle.py", line 880, in load_eof
    raise EOFError
EOFError

有人有任何想法吗?

3 个答案:

答案 0 :(得分:1)

显然,你正试图“挑选”一些不可挑选的东西(似乎是一个wx对象)。尝试仅用作参数“简单”对象(即内部没有图形对象),它应该更好地工作。 您还可以查看python nose unitest库,它允许您自动在多进程中运行测试。

答案 1 :(得分:0)

我建议您创建一个运行测试的单独脚本,然后您可以使用subprocess模块调用该脚本,为其提供要运行的测试的名称。

奖励是,您可以在持续集成服务器,夜间构建或其他不需要GUI的批处理类型的进程中使用相同的脚本。

答案 2 :(得分:-1)

使用fork生成子进程。这需要你做一些工作,但是会有效。

注意:multiprocessnig模块使用fork实现。


更新:仔细查看代码后,item viariable似乎不是pickleable(这是一个单词?)。我不认为你需要它,因为你可以用更简单的东西(价值或某种类型)来代替它。