【问题标题】:How to use mocking to compare real results如何使用模拟来比较真实结果
【发布时间】:2021-10-11 05:20:03
【问题描述】:

我有一个示例类,它读取保存的 Tensorflow 模型并运行预测

class Sample():
   ## all it does is creates a new column with predictions

   def __init__(self, tf_model):
      self.tf_model = tf_model

   def tf_process(self, x):

       ##some other preprocessing
       x["tf_predictions"] = self.tf_model.predict(x)
       return x
   
   def predict(self, x):
       predictions = self.tf_process(x)
       return predictions

无需加载模型的单元测试代码:

import unittest
import pandas as pd
from unittest import TestCase, mock
from my_package.sample_model import Sample

class TestSample(unittest.TestCase):

   def test_predict(self):
      with mock.patch("Sample.tf_process") as process:
         process.return_value = pd.DataFrame("hardcoded_value")
         #to check: process.return_value = Output (Sample.predict())
         

目标:

为了比较process.return_valueOutput of predict method in Sample,但要做到这一点,我仍然需要加载模型,我不明白mock 在这里有什么用,因为无论如何我都必须调用predict 方法将其与process.return_value 进行比较。任何建议都会有所帮助

【问题讨论】:

  • 嗯,这取决于你在测试什么。如果你想测试预测,你不能模拟它,那会违背目的。如果您想在不测试 predict 的情况下测试 tf_process,请改为模拟 predict。使用当前的模拟,您只能使用正确的参数测试 predict 调用 tf_process
  • @MrBeanBremen 我只想测试是否创建了tf_predictions 列?关于如何测试的任何建议。
  • 正如我所写 - 在这种情况下,您可以模拟 predict(不确定它属于哪个类)以返回一些合理的东西。

标签: python mocking pytest python-unittest pytest-mock


【解决方案1】:

我认为在你的情况下最好使用Mock()。你可以在没有patch() 的情况下创建非常好的和简单的测试。只需为初始化准备所有必要的模拟实例。

from unittest.mock import Mock


class TestSample(TestCase):
    def test_predict(self):
        # let's say predict() will return something... just an example
        tf = Mock(predict=Mock(return_value=(10, 20, 30)))
        df = pd.DataFrame({'test_col': (1, 2, 3)})
        df = Sample(tf).predict(df)
        # check column
        self.assertTrue('tf_predictions' in df.columns)
        # or check records
        self.assertEqual(
            df.to_dict('records'),
            [
                {'test_col': 1, 'tf_predictions': 10},
                {'test_col': 2, 'tf_predictions': 20},
                {'test_col': 3, 'tf_predictions': 30}
            ]
        )

当您需要对复杂服务进行测试时,它确实很有帮助。只是一个例子:

class ClusterService:
    def __init__(self, service_a, service_b, service_c) -> None:
        self._service_a = service_a
        self._service_b = service_b
        self._service_c = service_c
        # service_d, ... etc

    def get_cluster_info(self, name: str):
        self._service_a.send_something_to_somewhere(name)
        data = {
            'name': name,
            'free_resources': self._service_b.get_free_resources(),
            'current_price': self._service_c.get_price(name),
        }

        return ' ,'.join([
            ': '.join(['Cluster name', name]),
            ': '.join(['CPU', str(data['free_resources']['cpu'])]),
            ': '.join(['RAM', str(data['free_resources']['ram'])]),
            ': '.join(['Price', '{} $'.format(round(data['current_price']['usd'], 2))]),
        ])


class TestClusterService(TestCase):
    def test_get_cluster_info(self):
        cluster = ClusterService(
            service_a=Mock(),
            service_b=Mock(get_free_resources=Mock(return_value={'cpu': 100, 'ram': 200})),
            service_c=Mock(get_price=Mock(return_value={'usd': 101.4999})),
        )

        self.assertEqual(
            cluster.get_cluster_info('best name'),
            'Cluster name: best name ,CPU: 100 ,RAM: 200 ,Price: 101.5 $'
        )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2019-04-07
    • 2020-12-29
    相关资源
    最近更新 更多