dart power tools
DESCRIPTION
Increase the speed of Dart software delivery with unit testing, code analysis, headless browser testing, cross-browser and mobile testing, continuous integration, and automated deployments.TRANSCRIPT
Dart Power ToolsBrad Rydzewski & Matt Norris
@bradrydzewski @mattnorrisme
Dart 1.0!
github.com/bradrydzewski/dart-url-shortener
Demo
What will we learn?Build Dart appDatabase persistence TestDeploy
Language featuresToolsContinuous Integration
Client
Including Dartindex.html<html> ... <script type="application/dart” src="index.dart"></script>
<script src="packages/browser/dart.js"></script> ...</html>
Including Dartindex.html<html> ... <script type="application/dart” src="index.dart"></script>
<script src="packages/browser/dart.js"></script> ...</html>
Formindex.html...<input type="text" id="long_url" /><button id="btn">Shorten</button><a id="short_url” class="hidden"></a>...
index.dartvoid main() { querySelector("#btn") .onClick.listen(onClick);}...
Formindex.html...<input type="text" id="long_url" /><button id="btn">Shorten</button><a id="short_url” class="hidden"></a>...
index.dartvoid main() { querySelector("#btn") .onClick.listen(onClick);}...
Formindex.html...<input type="text" id="long_url" /><button id="btn">Shorten</button><a id="short_url” class="hidden"></a>...
index.dartvoid main() { querySelector("#btn") .onClick.listen(onClick);}...
Dart mainindex.html...<input type="text" id="long_url" /><button id="btn">Shorten</button><a id="short_url” class="hidden"></a>...
index.dartvoid main() { querySelector("#btn") .onClick.listen(onClick);}...
Attach listener to buttonindex.html...<input type="text" id="long_url" /><button id="btn">Shorten</button><a id="short_url” class="hidden"></a>...
index.dartvoid main() { querySelector("#btn") .onClick.listen(onClick);}...
index.dartvoid onClick(MouseEvent event) { HttpRequest request = new HttpRequest(); request.onReadyStateChange.listen((_) {
showText(request.responseText); });
... ... request.send();}
index.dartvoid onClick(MouseEvent event) { HttpRequest request = new HttpRequest(); request.onReadyStateChange.listen((_) {
showText(request.responseText); });
... ... request.send();}
index.dartvoid onClick(MouseEvent event) { HttpRequest request = new HttpRequest(); request.onReadyStateChange.listen((_) {
showText(request.responseText); });
... ... request.send();}
index.dartvoid onClick(MouseEvent event) { HttpRequest request = new HttpRequest(); request.onReadyStateChange.listen((_) {
showText(request.responseText); });
... ... request.send();}
Some sugarvoid showText(String hash) { var loc = window.location var url = "${loc.protocol}//${loc.host}/${hash}"; var urlShort = querySelector("#url_short") ..attributes["href"] = url ..text = url ..classes.remove("hidden");}
More sugar, please!void showText(String hash) { var loc = window.location var url = "${loc.protocol}//${loc.host}/${hash}"; var urlShort = querySelector("#url_short") ..attributes["href"] = url ..text = url ..classes.remove("hidden");}
github.com/bradrydzewski/dart-url-shortener
Demo
I must have put a decimal point in the wrong place.I always mess up some mundane detail!
Client tests
test_index.dart import 'package:unittest/unittest.dart';import 'package:unittest/html_enhanced_config.dart';...main() { useHtmlEnhancedConfiguration();
test("url includes scheme", () { expect(isValidUrl(“www.yahoo.com”), false); expect(isValidUrl(“http://www.yahoo.com”), true); });
HTML unit test
test_index.dart import 'package:unittest/unittest.dart';import 'package:unittest/html_enhanced_config.dart';...main() { useHtmlEnhancedConfiguration();
test("url includes scheme", () { expect(isValidUrl(“www.yahoo.com”), false); expect(isValidUrl(“http://www.yahoo.com”), true); });
HTML unit test
test_index.dart import 'package:unittest/unittest.dart';import 'package:unittest/html_enhanced_config.dart';...main() { useHtmlEnhancedConfiguration();
test("url includes scheme", () { expect(isValidUrl(“www.yahoo.com”), false); expect(isValidUrl(“http://www.yahoo.com”), true); });
HTML unit test
HTML unit test
content_shell$ content_shell --dump-render-tree web/test_index.html
Content-Type: text/plainPASSAll 2 tests passedCollapse All
Server
Web frameworkserver.dartimport 'package:start/start.dart';
start(public: 'web', port: port).then((Server app) { app.post('/’).listen((request) { ... });});
Web frameworkserver.dartimport 'package:start/start.dart';
start(public: 'web', port: port).then((Server app) { app.post('/’).listen((request) { ... });});
server.dart void main() { ... app.post("/").listen((request) { String url = request.param('url'); String hash = toHash(url); client.set(hash, url).then((_)=>request.response.json(hash);); }); ...
server.dart void main() { ... app.post("/").listen((request) { String url = request.param('url'); String hash = toHash(url); client.set(hash, url).then((_)=>request.response.json(hash);); }); ...
server.dart void main() { ... app.post("/").listen((request) { String url = request.param('url'); String hash = toHash(url); client.set(hash, url).then((_)=>request.response.json(hash);); }); ...
server.dart void main() { ... app.post("/").listen((request) { String url = request.param('url'); String hash = toHash(url); client.set(hash, url).then((_)=>request.response.json(hash)); }); ...
server.dart void main() { ... app.get('/:hash').listen((request) { String hash = request.param('hash'); client.get(hash).then((val) => request.response.redirect(val)); }); ...
server.dart void main() { ... app.get('/:hash').listen((request) { String hash = request.param('hash'); client.get(hash).then((val) => request.response.redirect(val)); }); ...
server.dart void main() { ... app.get('/:hash').listen((request) { String hash = request.param('hash'); client.get(hash).then((val) => request.response.redirect(val)); }); ...
Server tests
server_tests.dartimport 'package:unittest/unittest.dart';import 'package:unittest/vm_config.dart';import 'server.dart' as server;
void main() { useVMConfiguration();
String URL = 'http://www.meetup.com/gdg-silicon-valley’;
test('HashURL', () { expect(server.toHash(URL), isNotNull); expect(server.toHash(URL), '287b6d95'); ...
server_tests.dartimport 'package:unittest/unittest.dart';import 'package:unittest/vm_config.dart';import 'server.dart' as server;
void main() { useVMConfiguration();
String URL = 'http://www.meetup.com/gdg-silicon-valley’;
test('HashURL', () { expect(server.toHash(URL), isNotNull); expect(server.toHash(URL), '287b6d95'); ...
server_tests.dartimport 'package:unittest/unittest.dart';import 'package:unittest/vm_config.dart';import 'server.dart' as server;
void main() { useVMConfiguration();
String URL = 'http://www.meetup.com/gdg-silicon-valley’;
test('HashURL', () { expect(server.toHash(URL), isNotNull); expect(server.toHash(URL), '287b6d95'); ...
Run the test$ dart server_tests.dart
PASS: HashURL
Deployment
Deployment$ heroku create
$ heroku addons:add redistogo
$ git push heroku
$ heroku config:add BUILDPACK_URL=...
How many OS/browser combos?
200+
Cross-browser testing
Dart + Seleniumbrowser_tests.dartvoid main() { ...
driver = WebDriver.createDriver( url: “http://localhost:4444/wd/hub”, desiredCapabilities: Capabilities.android);
...
Dart + Seleniumbrowser_tests.dartvoid main() {
...
test('integration test', (){ return driver.findElement(new By.id('url_long')) .then((elem)=>elem.sendKeys("https://www.dartlang.org/")) ...
.then((attr)=>expect(attr, "https://www.dartlang.org/")) ...
saucelabs.com/tests
Sauce Labs
Continuous Integration
Build Configurationimage: dartscript: - pub get - pub build - dart bin/server_test.dartdeploy: heroku: app: dart-demo
Build Configurationimage: dartscript: - pub get - pub build - dart bin/server_test.dartdeploy: heroku: app: dart-demo
Build Configurationimage: dartscript: - pub get - pub build - dart bin/server_test.dartdeploy: heroku: app: dart-demo
What have we learned?✓ Built Dart app✓ Client & server✓ Database persistence ✓ Tested✓ Deployed
✓ Language features✓ Tools✓ Continuous Integration
What should you do?
Try DartTest thingsUse toolsDeploy!
Thank you!Questions?