在unittest中使用assertRaises引发了自定义异常但未捕获

时间:2016-01-19 03:19:31

标签: python unit-testing ssh paramiko

我编写了一个用于测试我的SSH模块的单元测试,并添加了一个自定义的' RemoteCmdError' info user remote命令的异常类已经失败。但是当我将这个测试用例添加到我的单元测试中时,它总是失败了。 show' AssertionError:RemoteCmdError未引发'虽然例外已经提出。我试图修改例外名称&使用官方示例重写我的自定义类,但它都没有工作。有什么不对??我该如何解决?这是我的代码:

/BaseLibrary/SSH.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import logging.config
import json

logger = logging.getLogger(__name__)
with open("logging.json") as f:
    config = json.load(f)
logging.config.dictConfig(config)

import paramiko
import socket

class SSHClient:
    def __init__(self, hostname, username, password, port=22):
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ssh.connect(hostname, username=username, password=password, port=port, look_for_keys=False, timeout=10)

    def run(self, cmd):
        stdin, stdout, stderr = self.ssh.exec_command(cmd, timeout=3600)
        stdin.close()

        try:
            res = "".join(stdout.readlines())
            if stdout.channel.recv_exit_status() != 0:
                error_msg = "Remote command error"
                raise RemoteCmdError(error_msg, cmd, res)
        except RemoteCmdError as e:
            logger.exception("%s (RemoteCmd='%s', ErrorMsg=%s)" %(e.msg, e.cmd, e.res))

        return res.strip() , stdout.channel.recv_exit_status()

    def __del__(self):
        self.ssh.close()

class WindowsSSHClient(SSHClient):
    def powershell(self, cmd):
        prefix = 'powershell '
        powershell_cmd = prefix + cmd
        res = self.run(powershell_cmd)
        return res

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class RemoteCmdError(Error):
    def __init__(self, msg, cmd, res, *args):
        super(RemoteCmdError, self).__init__(self, *args)
        self.args = args
        self.msg = msg
        self.cmd = cmd
        self.res = res

/Tests/test_SSH.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from BaseLibrary.SSH import *
import unittest

class Basic_WindowsSSHClient(unittest.TestCase):

    def setUp(self):
        self.hostname = "10.77.0.123"
        self.username = "Administrator"
        self.password = "1234"

    def tearDown(self):
        self.client = None

    def test_powershell_fail(self):
        self.client = WindowsSSHClient(self.hostname, self.username, self.password)
        with self.assertRaises(RemoteCmdError):
            self.client.powershell("Get-Item afilethatdoesntexist.txt")

控制台输出:

test@virtual-machine:~/$ python -m unittest Tests.test_SSH.Basic_WindowsSSHClient.test_powershell_fail
2016-01-19 09:38:10,557 - [INFO] - paramiko.transport - Connected (version 2.0, client WeOnlyDo)
2016-01-19 09:38:10,699 - [INFO] - paramiko.transport - Authentication (password) successful!
2016-01-19 09:38:11,526 - [ERROR] - BaseLibrary.SSH - Remote command error (RemoteCmd='powershell Get-Item afilethatdoesntexist.txt', ErrorMsg=Get-Item : Cannot find path 
'C:\Users\Administrator\Desktop\afilethatdoesntexist.txt' because it does not 
exist.
At line:1 char:1
+ Get-Item afilethatdoesntexist.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\Admini...doesntexist.t 
   xt:String) [Get-Item], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetIt 
   emCommand

)
Traceback (most recent call last):
  File "BaseLibrary/SSH.py", line 29, in run
    raise RemoteCmdError(error_msg, cmd, res)
RemoteCmdError
F
======================================================================
FAIL: test_powershell_fail (Tests.test_SSH.Basic_WindowsSSHClient)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "Tests/test_SSH.py", line 75, in test_powershell_fail
    self.client.powershell("Get-Item afilethatdoesntexist.txt")
AssertionError: RemoteCmdError not raised

----------------------------------------------------------------------
Ran 1 test in 1.066s

FAILED (failures=1)

1 个答案:

答案 0 :(得分:2)

记录后,您需要重新引发异常

try:
    res = "".join(stdout.readlines())
    if stdout.channel.recv_exit_status() != 0:
        error_msg = "Remote command error"
        raise RemoteCmdError(error_msg, cmd, res)
except RemoteCmdError as e:
    logger.exception("%s (RemoteCmd='%s', ErrorMsg=%s)" %(e.msg, e.cmd, e.res))
    raise  # HERE