-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Metadata API: comprehensive de/serialization testing #1391
Comments
Is this a place where fuzzing could add some confidence that would be harder to achieve with designed test cases? Cc @sechkova |
pasting a related comment from chat:
parameterized testing could help now that we have the smaller classes. There are test dependencies for that but even plain unittest (on python>3.4) includes SubTest that could be used: testdata = {
"with attr": "{'attr': 'value'}",
"missing attr": "{}",
}
def test_data(self):
for case, data in testdata.items():
with self.subTest(case=case):
# deserialize/serialize data here The value is that A) error message will now include An additional decision here is what checks need to be made:
|
I started working on tests for that.
''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(len)) |
My advice is to not get into detailed tests where different variations of attributes are tested, at least not yet: it's so easy to end up with more and more test code where no-one is really sure what actually gets tested. I'd like to see readable test cases where I'm able to immediately see e.g. that Targets is tested with
in a way that it's easy to add new cases when we notice that something would be useful I'm hoping this could be accomplished so that we only define the test data multiple times, and the actual test code is always the same... You actually already do this in at least invalid delegations (EDIT: actually that may have been me). So hypothetical example: valid_target_cases = {
"all attributes": TODO-TEST-DATA1,
"empty targets": TODO-TEST-DATA2,
"no delegations": TODO-TEST-DATA3,
# Add things here when new ideas appear
}
def test_serialization_valid_targets(self):
for case, data in valid_target_cases.items():
with self.subTest(case=case):
targets = Targets.from_dict(copy.deepcopy(data))
self.assertDictEquals(targets.to_dict(), data)
# maybe other checks? This is of course worth it (compared to current way of testing) only if the bits with TODO are easy to construct and the whole thing remains readable. It may be worth experimenting with just writing minimal json by hand at least in the simplest classes... but also with generating the data -- maybe using functions written for the purpose, or just by defining fragments that can be re-used in many tests ( I'm waving my hands wildly as you can see (so no hard opinions here) but I do believe more comprehensive testing requires some level of parameterizing: otherwise the test code becomes a mess no-one wants to touch. |
I have a couple of questions/observations here:
|
What I would like to see in serialization testing is that each component has well defined test sets and minimal amount of code. These test datasets should be easy to read so when I open the file I can quickly check if a case is handled and if not I can easily create a new test case. There are two main issues with the current code, and these complaints partly apply to the PR here:
There's probably many ways to address these. I have a quick prototype of DelegatedRole testing (it's three commits on top of this PR: one is just a generic example, one is the helper descriptor, and the last commit contains the actual DelegatedRole test): https://github.com/jku/tuf/commits/test-example
I did not spend a lot of time on this so there's probably weird decisions in the code (does it make sense for the test input to be str? 🤷 does the decorator really need three nested functions? 🤷 how does one actually fill in constant snippets into json since f-strings and json both want to use double quote 🤷), please consider it a prototype |
Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
The idea of this commit is to separate (de)serialization testing outside test_api.py and make sure we are testing from_dict/to_dict for all possible valid data for all classes. Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
The idea of this commit is to separate (de)serialization testing outside test_api.py and make sure we are testing from_dict/to_dict for all possible valid data for all classes. Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
The idea of this commit is to separate (de)serialization testing outside test_api.py and make sure we are testing from_dict/to_dict for all possible valid data for all classes. Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
The idea of this commit is to separate (de)serialization testing outside test_api.py and make sure we are testing from_dict/to_dict for all possible valid data for all classes. Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
The idea of this commit is to separate (de)serialization testing outside test_api.py and make sure we are testing from_dict/to_dict for all possible valid data for all classes. Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
The idea of this commit is to separate (de)serialization testing outside test_api.py and make sure we are testing from_dict/to_dict for all possible valid data for all classes. Jussi in his comment here: theupdateframework#1391 (comment) proposed using decorators when creating comprehensive testing for metadata serialization. The main problems he pointed out is that: 1) there is a lot of code needed to generate the data for each case 2) the test implementation scales badly when you want to add new cases for your tests, then you would have to add code as well 3) the dictionary format is not visible - we are loading external files and assuming they are not changed and valid In this change, I am using a decorator with an argument that complicates the implementation of the decorator and requires three nested functions, but the advantages are that we are resolving the above three problems: 1) we don't need new code when adding a new test case 2) a small amount of hardcoded data is required for each new test 3) the dictionaries are all in the test module without the need of creating new directories and copying data. Signed-off-by: Martin Vrachev <[email protected]>
It's really hard to avoid de/serialization issues like #1389 and #1386
Can we improve the testing so a large number of different json representatations are deserialized (and then serialized), so that things like missing fields and e.g. empty containers are tested -- I'm not even talking about testing broken data (that would be nice but not first priority), just valid data in all possible forms.
This should be much more doable now that we have the smaller objects: testing the "complete API" of small classes is a much more reasonable goal than testing the whole metadata.
I don't have practical advice right now how this can be implemented without a lot of inline dictionaries...
The text was updated successfully, but these errors were encountered: