SELECT IIF(CalculationMethod = x and Price * coefficient < Amount, Amount, Price * coefficient) as CalculatedAmount
FROM aTable
Вы могли использовать метакласс для динамичной вставки тестов. Это хорошо работает для меня:
import unittest
class UnderTest(object):
def f1(self, i):
return i + 1
def f2(self, i):
return i + 2
class TestMeta(type):
def __new__(cls, name, bases, attrs):
funcs = [t for t in dir(UnderTest) if t[0] == 'f']
def doTest(t):
def f(slf):
ut=UnderTest()
getattr(ut, t)(3)
return f
for f in funcs:
attrs['test_gen_' + f] = doTest(f)
return type.__new__(cls, name, bases, attrs)
class T(unittest.TestCase):
__metaclass__ = TestMeta
def testOne(self):
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()
Вот мой любимый подход к "семейству связанных тестов". Мне нравятся явные подклассы TestCase, который выражает типичные функции.
class MyTestF1( unittest.TestCase ):
theFunction= staticmethod( f1 )
def setUp(self):
self.matrix1 = numpy.ones((5,10))
self.matrix2 = numpy.identity(5)
def testOutputShape( self ):
"""Output of functions be of a certain shape"""
output = self.theFunction(self.matrix1, self.matrix2)
fail_message = "%s produces output of the wrong shape" % (self.theFunction.__name__,)
self.assertEqual(self.matrix1.shape, output.shape, fail_message)
class TestF2( MyTestF1 ):
"""Includes ALL of TestF1 tests, plus a new test."""
theFunction= staticmethod( f2 )
def testUniqueFeature( self ):
# blah blah blah
pass
class TestF3( MyTestF1 ):
"""Includes ALL of TestF1 tests with no additional code."""
theFunction= staticmethod( f3 )
Добавьте функцию, добавьте подкласс MyTestF1
. Каждый подкласс MyTestF1 включает все тесты в MyTestF1 без дублированного кода любого вида.
Уникальные функции обрабатываются очевидным способом. Новые методы добавляются к подклассу.
Это абсолютно совместимо с unittest.main()
Если Вы уже используете нос (и некоторые Ваши комментарии предполагают, что Вы), почему не делают Вас, просто используют Тестовые Генераторы, которые являются самым простым способом реализовать параметрические тесты, с которыми я столкнулся:
Например:
from binary_search import search1 as search
def test_binary_search():
data = (
(-1, 3, []),
(-1, 3, [1]),
(0, 1, [1]),
(0, 1, [1, 3, 5]),
(1, 3, [1, 3, 5]),
(2, 5, [1, 3, 5]),
(-1, 0, [1, 3, 5]),
(-1, 2, [1, 3, 5]),
(-1, 4, [1, 3, 5]),
(-1, 6, [1, 3, 5]),
(0, 1, [1, 3, 5, 7]),
(1, 3, [1, 3, 5, 7]),
(2, 5, [1, 3, 5, 7]),
(3, 7, [1, 3, 5, 7]),
(-1, 0, [1, 3, 5, 7]),
(-1, 2, [1, 3, 5, 7]),
(-1, 4, [1, 3, 5, 7]),
(-1, 6, [1, 3, 5, 7]),
(-1, 8, [1, 3, 5, 7]),
)
for result, n, ns in data:
yield check_binary_search, result, n, ns
def check_binary_search(expected, n, ns):
actual = search(n, ns)
assert expected == actual
Производит:
$ nosetests -d
...................
----------------------------------------------------------------------
Ran 19 tests in 0.009s
OK
Метаклассы являются одной опцией. Другая опция состоит в том, чтобы использовать a TestSuite
:
import unittest
import numpy
import funcs
# get references to functions
# only the functions and if their names start with "matrixOp"
functions_to_test = [v for k,v in funcs.__dict__ if v.func_name.startswith('matrixOp')]
# suplly an optional setup function
def setUp(self):
self.matrix1 = numpy.ones((5,10))
self.matrix2 = numpy.identity(5)
# create tests from functions directly and store those TestCases in a TestSuite
test_suite = unittest.TestSuite([unittest.FunctionTestCase(f, setUp=setUp) for f in functions_to_test])
if __name__ == "__main__":
unittest.main()
Не протестировали. Но это должно хорошо работать.
Проблема с этим подходом состоит в том, что, если какой-либо элемент списка проваливает тест, более поздние элементы не становятся протестированными.
При рассмотрении его с точки зрения, что, если тест перестал работать, который очень важен и весь пакет недопустим, то не имеет значения, что другие элементы не будут протестированы, потому что 'эй, у Вас есть ошибка зафиксировать'.
После того как тот тест передает, другие тесты будут затем работать.
По общему признанию существует информация, которая будет получена от знания, которого перестали работать другие тесты, и это может помочь с отладкой, но кроме этого, предположить, что любой отказ при испытании является отказом целого приложения.
Приведенный выше код метакласса имеет проблемы с носом, потому что носовой параметр wantMethod в его selector.py смотрит на __ name __
данного метода тестирования, а не на ключ атрибута dict.
Чтобы использовать метод тестирования, определенный метаклассом, с носом, имя метода и ключ словаря должны быть одинаковыми и иметь префикс для обнаружения с помощью носа (то есть с помощью 'test _').
# test class that uses a metaclass
class TCType(type):
def __new__(cls, name, bases, dct):
def generate_test_method():
def test_method(self):
pass
return test_method
dct['test_method'] = generate_test_method()
return type.__new__(cls, name, bases, dct)
class TestMetaclassed(object):
__metaclass__ = TCType
def test_one(self):
pass
def test_two(self):
pass
Здесь вам не нужно использовать Мета-классы. Простой цикл отлично подходит. Взгляните на пример ниже:
import unittest
class TestCase1(unittest.TestCase):
def check_something(self, param1):
self.assertTrue(param1)
def _add_test(name, param1):
def test_method(self):
self.check_something(param1)
setattr(TestCase1, 'test_'+name, test_method)
test_method.__name__ = 'test_'+name
for i in range(0, 3):
_add_test(str(i), False)
После выполнения for в TestCase1 есть 3 метода тестирования, которые поддерживаются как носом, так и юниттестом.
.