参数化 RuleBasedStateMachine

Parametrized RuleBasedStateMachine

观看 https://www.youtube.com/watch?v=zi0rHwfiX1Q 之后,我尝试将示例从 C(实现)和 Erlang(测试)移植到 Python 和假设。鉴于此实现(rem 函数模拟 % 的 C 行为):

import math


def rem(x, y):
    res = x % y
    return int(math.copysign(res,x))


class Queue:
    def __init__(self, capacity: int):
        self.capacity = capacity + 1
        self.data = [None] * self.capacity
        self.inp = 0
        self.outp = 0

    def put(self, n: int):
        self.data[self.inp] = n
        self.inp = (self.inp + 1) % self.capacity

    def get(self):
        ans = self.data[self.outp]
        self.outp = (self.outp + 1) % self.capacity
        return ans

    def size(self):
        return rem((self.inp - self.outp), self.capacity)

和这个测试代码

import unittest

from hypothesis.stateful import rule, precondition, RuleBasedStateMachine
from hypothesis.strategies import integers

from myqueue import Queue

class QueueMachine(RuleBasedStateMachine):

    cap = 1

    def __init__(self):
        super().__init__()
        self.queue = Queue(self.cap)
        self.model = []

    @rule(value=integers())
    @precondition(lambda self: len(self.model) < self.cap)
    def put(self, value):
        self.queue.put(value)
        self.model.append(value)

    @rule()
    def size(self):
        expected = len(self.model)
        actual = self.queue.size()
        assert actual == expected

    @rule()
    @precondition(lambda self: self.model)
    def get(self):
        actual = self.queue.get()
        expected = self.model[0]
        self.model = self.model[1:]
        assert actual == expected

TestQueue = QueueMachine.TestCase

if __name__ == "__main__":
    unittest.main()

实际问题 是如何使用假设对 QueueMachine.cap 进行参数化而不是在测试中手动设置它 class.

您可以在 initialize 方法中设置 self.queue 而不是 __init__,使用适合容量的整数策略。