Parser Tests¶
As with everything, n6 comes with a class simplifying the task at hand.
In this case, we’ll have to look at the ParserTestMixin in the
n6datasources.tests.parsers._parser_test_mixin module.
We’ll configure the test case by setting relevant
class attributes and then implement input and expected output
data as the method cases.
If you want to see all possible class attributes to set, you should read the class definition itself. We will focus only on the most important ones.
RECORD_DICT_CLASS- the class of the mappings yielded by the parser’sparsemethod. It defaults toRecordDictas most parsers use it. However, blacklist parsers useBLRecordDictso if the tested parser is the blacklist one be sure to set the attribute of your test case class toBLRecordDict(imported fromn6lib.record_dict).PARSER_CONSTANT_ITEMS- same asconstant_itemsinBaseParser.PARSER_CLASS- the class of the tested parser.PARSER_BASE_CLASS- the base class of the tested parser.PARSER_SOURCE- the source identifier in the{source provider}.{source channel}format (corresponds to the first two parts of parser’sdefault_binding_key).ASSERT_RESULTS_EQUAL- the name of the test case method that will be used to test whether actual results are equal to the expected results. Defaults toassertEqualbut can be changed, for example toassertCountEqualto not care about the order of the items inside collections.
Example test case could look like so:
class TestMyParserSimpleCase(ParserTestMixin, unittest.TestCase)
PARSER_SOURCE = 'source-provider.source-channel'
PARSER_CLASS = MyParser
PARSER_BASE_CLASS = BaseParser
PARSER_CONSTANT_ITEMS = {
'restriction': 'public',
'confidence': 'low',
'category': 'dos-victim',
}
Then we can implement assertions by yielding pairs (2-tuples) of: input data and expected output.
class TestMyParserSimpleCase(ParserTestMixin, unittest.TestCase)
PARSER_SOURCE = 'source-provider.source-channel'
PARSER_CLASS = MyParser
PARSER_BASE_CLASS = BaseParser
PARSER_CONSTANT_ITEMS = {
'restriction': 'public',
'confidence': 'medium',
'category': 'server-exploit',
}
def cases(self):
yield (
'{"tag": "example.com,some1.2019-10-11T23:59:59"}',
[
dict(
fqdn='example.com',
name='some1',
time='2019-10-11 23:59:59',
),
]
)
yield (
'{"tag": "example.org,some2.2019-10-12T01:02:03"}',
[
dict(
fqdn='example.org',
name='some2',
time='2019-10-12 01:02:03',
),
]
)
Of course, the input and resulting data fields will depend on the tested source.
ParserTestMixin automatically covers testing the id and source
fields as well as any fields that the PARSER_CONSTANT_ITEMS mapping
includes. We need to provide the values for any other fields in the
expected results.
It is also worth mentioning that the ParserTestMixin class also provides
a helper method for creating blacklist items, get_bl_items, which is
very useful when testing blacklist parsers.