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