The test suite in the Dart version of the ICE Code Editor is a slave to the JavaScript included in it. And it is making my test suite messier than I would like. Unfortunately, I do not think that I have much choice in the matter.
Actually, I do have a choice. I am intentionally hiding the JavaScript nature of ICE from developers. I want them to be able to create an instance of ICE with just a couple lines of Dart and no icky JavaScript:
<head> <script type="application/dart"> import 'package:ice_code_editor/ice.dart' as ICE; main()=> new ICE.Full(); </script> </head>Since there is JavaScript in ICE (the actual code editor is ACE code editor), this means that I have to dynamically add
<script> tags to pull in the JavaScript.This works quite well in the application code, but is a mess in the test suite. I have code that prevents multiple
<script> tags from being added for ACE (yes, it is a bit confusing with ICE and ACE—I chose ICE before I had even heard of ACE). But the preventative duplicate <script> tag is the only nod that I give to testing in the application code.It is never a good idea to optimize for the testing environment, so I do not intend to do so today. But today may be the day that the current approach gets out of control. Currently, the test suite looks like:
library ice_test;
// import libraries for testing here...
part 'editor_test.dart';
part 'store_test.dart';
part 'gzip_test.dart';
part 'full_test.dart';
main(){
editor_tests();
store_tests();
gzip_tests();
full_tests();
}I want to extract the dialog tests out of full_test.dart, which is currently 561 lines of code and nigh impossible to search for the group that I want.I pull the copy-related tests out into a
copy_dialog_test.dart file:part of ice_test;
copy_dialog_tests() {
group("Copy Dialog", (){
var editor;
setUp(()=> editor = new Full(enable_javascript_mode: false));
tearDown(() {
document.query('#ice').remove();
new Store().clear();
});
test("can open copy dialog", (){
helpers.click('button', text: '☰');
helpers.click('li', text: 'Make a Copy');
expect(
queryAll('button'),
helpers.elementsContain('Save')
);
});
// ...
});
}As the opening declaration indicates, I make this part of the whole test suite rather than a smaller library. I found it best to keep all of the code in the same execution isolate—again mainly due to js-interop concerns. Since this is part of the whole ice_test library, I need to mark it (and the other dialog tests) as a part, and run the test function:library ice_test;
// imports...
part 'editor_test.dart';
part 'store_test.dart';
part 'gzip_test.dart';
part 'full_test.dart';
part 'full/copy_dialog_test.dart';
part 'full/share_dialog_test.dart';
part 'full/open_dialog_test.dart';
part 'full/new_project_dialog_test.dart';
part 'full/rename_dialog_test.dart';
part 'full/save_dialog_test.dart';
part 'full/remove_dialog_test.dart';
main(){
editor_tests();
store_tests();
gzip_tests();
full_tests();
copy_dialog_tests();
share_dialog_tests();
open_dialog_tests();
new_project_dialog_tests();
rename_dialog_tests();
save_dialog_tests();
remove_dialog_tests();
}
I am not thrilled at the large number of parts. That said, it is not as horrible as I had feared. All 50+ tests still pass. The complexity of the test organization is handled in one file—albeit in two places. Even if I coud split this test suite out into libraries, the full tests would likely be in the same library and it would not end up much cleaner.Overall, I think this approach is probably worth the parts hassle (and, really, it's not much of a hassle). Instantly knowing exactly where all copy-dialog tests (or any other dialog tests) are located is going to help immensely.
Day #766
No comments:
Post a Comment