summaryrefslogtreecommitdiffstats
path: root/misc/testsuite/lib/TestCase.py
blob: 654f965a5be874b68454945ce15f1df53ca3de6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#!/usr/bin/env python
# encoding: utf-8
"""
W3CLikCheckerClient.py
Simple client lib to interact with the W3C Link Checker

Created by olivier Thereaux on 2008-01-22.
Copyright (c) 2008 W3C. Licensed under the W3C Software License
http://www.w3.org/Consortium/Legal/copyright-software
"""

import sys
import os
import re
import unittest
from random import choice
from ValidatorsAPIs import W3CValidatorHTTP
import xml.etree.cElementTree as ET

class ValidatorTestCase(unittest.TestCase):
    """Atomic Test Case for validator test suite"""
    def __init__(self, title=None, description=None, docURI=None, expectResults=None, checker=None):
        if docURI:
            self.docURI = docURI
        else: 
            self.docURI = ""
        if description:
            self.description = description
        else:
            self.description = u""
        if title:
            self.title = title
        else:
            self.title = self.description
        if isinstance(expectResults, dict):
            self.expectResults = expectResults
        else:
            self.expectResults = dict()
        if checker != None:
            self.checker = checker
        else:
            self.checker = W3CValidatorHTTP()
        self._testMethodName= "run_testcase"

    def shortDescription(self):
        return self.title

    def run_testcase(self):
        """Run a validator test case
        We first remove irrelevant result keys in the validation results,
        and compare that to the expected results
        """
        (res, err) = self.checker.call_check(self.docURI)
        self.assertEqual(err, None)
        results = self.checker.parse_response(res)
        results_filtered = dict()
        for result_key in self.expectResults.iterkeys():
            if results.has_key(result_key):
                # this is an interesting hack to state that we expect 
                #   at least some number of errors (or warnings) but don't specify how many
                if self.expectResults[result_key] == "yes" and int(results[result_key]) > 0:
                    results[result_key] = "yes"
                results_filtered[result_key] = results[result_key]
            
        self.assertEqual(results_filtered, self.expectResults)

class ValidatorTestSuite:
    """A Validator test suite is a flattened tree of test collections and test cases"""
    def __init__(self, checker=None):
        if checker == None:
            self.checker = None # leave undefined
        else:
            self.checker = checker
        self.collections= list()

    def randomId(self):
        """
        return a randomized identifier for test collections or cases that do not have one
        Kudos to http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/526619
        """
        return ''.join([choice('bcdfghklmnprstvw')+choice('aeiou') for i in range(4)])

    def readTestSuiteFile(self, test_file):
        test_file_handle = open(test_file, 'r')
        try:
            tree = ET.parse(test_file_handle)
            ts_node = tree.getroot()
        except SyntaxError, v:
            raise v
        return ts_node

    def readTestCollection(self, collection_node, level=None):
        """read a test collection from a given ElementTree collection node
        The collection can have test cases as children (which will be read and returned)"""
        if level == None:
            level = 0
        testcollection = ValidatorTestCollection()
        testcollection.level = level
        if collection_node.attrib.has_key("id"):
            testcollection.collection_id = collection_node.attrib["id"]
        else:
            testcollection.collection_id = self.randomId()
        
        for child_node in collection_node.getchildren():
            if child_node.tag == "{http://purl.org/dc/elements/1.1/}title":
                testcollection.title = child_node.text
            if child_node.tag == "test":
                try:
                    testcase = self.readTestCase(child_node)
                except:
                    testcase = None
                if testcase != None:
                    testcollection.addTest(testcase)
        if collection_node.tag == "collection":
            self.collections.append(testcollection)
        for child_node in collection_node.getchildren():
            if child_node.tag == "collection":
                self.readTestCollection(child_node, level=level+1)


    def readTestCase(self, testcase_node):
        """read metadata for a test case from an elementTree testcase node"""
        try:
            title = testcase_node.findtext(".//{http://purl.org/dc/elements/1.1/}title")
        except:
            title = ""
        try:
            descr = testcase_node.findtext(".//{http://www.w3.org/1999/xhtml}p")
        except:
            descr = ""
        test_uri = ""
        test_uri = testcase_node.findtext(".//uri")
        expect_elt = testcase_node.find(".//expect")
        expected = dict()
        for child_expect in expect_elt.getchildren():
            expected[child_expect.tag] = child_expect.text
        case = ValidatorTestCase(title=title, description=descr, docURI=test_uri, expectResults=expected, checker=self.checker)
        return case

class ValidatorTestCollection(unittest.TestSuite):
    """subclassing the TestSuite from the unittest framework to add identifier and title"""
    def __init__(self):
        super(ValidatorTestCollection, self).__init__()
        self.collection_id = None
        self.level = None
        self.title = None
                    

class ValidatorTestCase_UT(unittest.TestCase):
    """Sanity Check for ValidatorTestCase classe"""
    def test_init_default(self):
        """Test initialization of a default ValidatorTestCase Object"""
        default_tc = ValidatorTestCase()
        self.assertEqual(
            [default_tc.title, default_tc.description, default_tc.docURI, default_tc.expectResults],
            [u'', u'', '', dict()]
        )

class ValidatorTestSuite_UT(unittest.TestCase):
    """Sanity Check for ValidatorTestSuite classe"""
    
    def getSamplefile(self, filename):
        libdir = os.path.dirname(os.path.abspath(__file__))
        sampledir = os.path.join(os.path.split(libdir)[0], "samples")
        samplefile = os.path.join(sampledir, filename)
        return samplefile
        
    def test_init_default(self):
        """Test initialization of a default ValidatorTestSuite Object"""
        default_ts = ValidatorTestSuite()
    
    def test_readTestSuiteFile(self):
        """Test reading a sample Test Suite file"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("testsuite.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        self.assertEquals(node.tag, "testsuite")
        
    def test_readTestCollection(self):
        """Test reading a sample test collection from a parsed test suite file"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("collection.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals(len(default_ts.collections), 1)

    def test_readTestCollection_2(self):
        """Test parsing a sample test collection for its id and title"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("collection.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals(
            [default_ts.collections[0].collection_id, default_ts.collections[0].title], 
            ["valid", "Valid Documents"])
    
    def test_readTestCase(self):
        """Test reading a test case from a parsed test suite file"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("testcase.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals(default_ts.collections[0].countTestCases(), 1)

    def test_readTestCase_2(self):
        """Test reading a test case and check URI"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("testcase.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals(default_ts.collections[0]._tests[0].docURI, "http://qa-dev.w3.org/wmvs/HEAD/dev/tests/html20.html")

    def test_readTestCase_3(self):
        """Test reading a test case and check description"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("testcase.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals(default_ts.collections[0]._tests[0].description, "HTML 2.0")

    def test_readTestCase_4(self):
        """Test reading a test case and check description"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("testcase.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals(default_ts.collections[0]._tests[0].shortDescription(), "HTML 2.0")
    def test_readTestCollection_recursive(self):
        """Test reading a sample test file with nested test collections - and count them"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("collection_nested.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals(len(default_ts.collections), 2)

    def test_readTestCollection_recursive(self):
        """Test reading a sample test file with nested test collections - and check their order and title"""
        default_ts = ValidatorTestSuite()
        samplefile = self.getSamplefile("collection_nested.xml")
        node = default_ts.readTestSuiteFile(samplefile)
        default_ts.readTestCollection(node)
        self.assertEquals([default_ts.collections[0].title, default_ts.collections[1].title], 
        ["Valid Documents", "Very Valid Documents"] )


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