如何测试使用第三方代码的方法

时间:2018-03-30 18:58:01

标签: python unit-testing

我有一个使用其他对象的类 - 来自scikit-learn的MultinomialNB。这个类有一个使用这个对象的函数,我想测试它。

测试它的正确方法是什么?我应该模拟从其他库导入的对象吗?我想这比编写这个函数需要花费更多的时间。

class MyClass:
    def __init__():
        self.model = MultinomialNB()
        self.extr = FeatureExtractor()

    ... other methods

    def get_most_coefficient_features(self):
        if len(self.model.coef_) != len(self.model.classes_):
            raise Exception("Different number of model features than coefs.")

        result = dict()
        for i, target in enumerate(self.model.classes_): 
            feats = sorted(zip(self.extr.features, self.model.coef_[i]), key=lambda t: t[1])
            result[target] = feats
        return result

我应该这样测试吗? (实际上我不能,因为我不能覆盖“coef_”,因为它是一个属性)

def test_get_most_coefficient_features(self):
    myclass_obj = MyClass()
    myclass_obj.extr.features = ["F1", "F2", "F3", "F4", "F5"]
    myclass_obj.model.classes_ = ["True", "False"]
    myclass_obj.model.coef_ = [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1]]
    res = myclass_obj.get_most_coefficient_features()
    exp_res = dict({"True": ["F1", "F2", "F3", "F4", "F5"], "False": ["F5", "F4", "F3", "F2", "F1"]})
    self.assertEqual(exp_res, res)

1 个答案:

答案 0 :(得分:0)

您的代码混合了算法核心和与外部库的某些交互。由于这种混杂的性质,似乎需要进行一些模拟来处理单元测试中的交互,我理解您的问题,以便您想知道这是否值得解决。

该算法非常复杂(我会说),足以证明一些测试工作的合理性。但是,是否值得进行必要的模拟测试原始代码(如注释中所述)取决于函数的重要性。

但是,在这种特殊情况下,可以通过简单的设计更改来消除模拟工作:您可以将要测试的算法与与外部库的交互分开:

def calc_most_coefficient_features(self, features, model_coefs, model_classes):
    if len(model_coefs) != len(model_classes):
        raise Exception("Different number of model features than coefs.")

    result = dict()
    for i, target in enumerate(model_classes): 
        feats = sorted(zip(features, model.coefs[i]), key=lambda t: t[1])
        result[target] = feats
    return result

def get_most_coefficient_features(self):
    return self.calc_most_coefficient_features(
        self.extr.features, self.model.coef_, self.model.classes_)

您现在可以使用单元测试来测试calc_most_coefficient_features,并使用集成测试来测试get_most_coefficient_features