Java Everywhere Again With DukeScript
Java Everywhere Again With DukeScript
org
Java Everywhere Again with DukeScript
JavaOne Hands on Lab 3962
Anton Epple
©2015 Anton Epple
Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
How it works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1. Getting started! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Developing DukeScript apps with the NetBeans Plugin . . . . . . . . . . . . . . . . . . . 2
The Generated Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Test Driven Development in a nutshell . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Unit Testing a ViewModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
www.dbooks.org
Preface
For many years, Java Swing enabled developers to write applications that could run on any operating
system. That all came to an end with the arrival of smart phones, tablets, and embedded computers.
In the enterprise, the desktop dominated for many years. In the meantime, however, almost every IT
project includes plans for a future where the application will need to be ported to mobile platforms.
Building native applications for all platforms requires special skills and is expensive in terms of both
maintenance and development.
We wanted to solve this problem, to make cross-platform development available for everyone again.
That’s why we developed DukeScript. In this lab you will learn how to use DukeScript and develop
Java applications that run on a lot of different devices.
How it works
The basic requirement to run DukeScript on a System is a JVM and a HTML5 renderer component.
On the Desktop we use Oracles HotSpot Virtual Machine and as a HTML-Renderer we use the
JavaFX WebView. In the Browser we use the bck2brwsr VM or TeaVM, and the Browser itself is the
HTML-Renderer. Here’s a little table to show what we use on supported platforms:
This architecture made it really easy to port to different platforms, and we can easily adapt to new
platforms if there is demand. But now without further ado, let’s start coding DukeScript!
1. Getting started!
It’s time to get your hands dirty. In this first exercise you’ll learn everything you need to create your
first DukeScript application using NetBeans.
Prerequisites
If you’re using this Lab at JavaONE 2015, the Laptops in the room are equipped with a VirtualBox
Image that has all the required software already installed. Just start VirtualBox, choose “HOL3962”
from the list of virtual machines and start it.
In case you prefer to use your own hardware you need at least JDK 7¹ and Maven 3.2.5². The best
IDE for developing DukeScipt is NetBeans which provides some extra features like hot swapping
of code and visual DOM Inspection. You can also use Eclipse or IntelliJ IDEA, but for this lab, we
assume you’re using NetBeans. For developing Android applications you need to install the Android
SDK³ and API Level 19, and for building for iOS you need the XCode 6⁴ and a Mac running OS X
10.9 or later.
www.dbooks.org
1. Getting started! 3
In Step 2 you need to specify the location where to create your project and the Maven coordinates.
Use “helloworld” as the application name and whatever package name you like. The Maven group
id will automatically be used as the base package of your application.
The next wizard steps ask to what platforms you would like to deploy. The options are Android,
iOS, Browser and NetBeans Plugin. In addition to that a Desktop Client will automatically created
for you. This is the one that is used for testing and debugging by default. Please select Android and
Browser as target platforms. (iOS requires the build to be run on a Mac, while the VM used in this
lab is running Windows 7)
1. Getting started! 4
If you choose Android as a platform here for the first time, the wizard will ask you where your
Android SDK is installed. Point it to “C:/Program Files(x86)/Android/Android SDK”
In the last wizard step you can choose between the available project templates. Let’s go for the
simplest one Knockout 4 Java Maven Archetype. Make sure you also check the checkbox to install
sample code.
www.dbooks.org
1. Getting started! 5
Select Archetype
After the project has been created the Wizard will automatically run a priming build which
downloads all the required artefacts. When this build is finished you’re ready to run the sample
application.
Generated Projects
• helloworld
– helloworld Client for Android
– helloworld Client for iOS
– helloworld Client for Web
– helloworld General Client Code
– helloworld JavaScript Libraries
The helloworld project is the parent project. It has common configuration for the subprojects and
can be used to build all the subprojects. The “General Client Code” is the project that contains the
actual Java code and the view definition. Use this to run, develop, test and debug your project.
For each target platform you selected in the wizard, there will also be a separate project. These
projects can be used to deploy, debug and test the project to the individual platforms. In NetBeans
each of the projects context menu has a submenu “custom” with entries that apply only to the
deployment platform. For example the iOS project has an entry that allows you to run in an iPad
simulator or deploy to a real iOS device, while the Android project has entries for running on an
attached Android device.
www.dbooks.org
1. Getting started! 7
Custom Actions
There’s also a separate project for JavaScript Libraries. If you want to create your own API, or if you
want to make calls from Java to JavaScript and back, this is where the code should go.
Summary
That’s it. By now you’ve learned how to create a new DukeScript project using your preferred
development environment. Now let’s have a closer look at the sample application!
2. Understanding the sample
application
Sometimes a demo is worth a thousand words, and often it’s easier to understand the concepts of a
technology when looking at an example and figuring out how the parts play together. In this part
of the lab I’ll try to guide you through that process. We’ll have a look at how the sample application
works. You’ll learn how View and ViewModel can work together while still being cleanly separated.
You can now play with the application. Below a little form there are six boxes with words. These
boxes show the text in the textfield. If you change that Text the words in the boxes will also update
immediately. If you click on the start button, the button will be disabled and the words will start
rotating. Also the stop button will be enabled now. you can use it to stop the rotation and reenable
the start button. You need to confirm that action in a dialog. There’s another button that will rotate
www.dbooks.org
2. Understanding the sample application 9
the boxes for just a few seconds and a button that will get the screen size and display it in the
textfield. So despite the simplicity of the UI there’s actually a lot to investigate, because all of the
logic is written in Java using the DukeScript APIs.
Enter archeype
The View
Let’s first have a look at how the view is defined, how the animation works and how the view is
bound to the model.
In the Project Tab, you can easily locate it under ‘Web Pages/pages’. The page is just simple HTML.
To preview it, right-click it and choose ‘View’ from the Menu. It will open in a browser. Now open
the file and have a look at it’s content. The head contains some CSS:
1 @-webkit-keyframes spin {
2 0% { -webkit-transform: rotate(0deg); }
3 100% { -webkit-transform: rotate(360deg); }
4 }
5
6 input {
7 width: 100%;
8 }
9
10 .rotate {
11 -webkit-animation-name: spin;
12 -webkit-animation-duration: 3s;
13 -webkit-animation-iteration-count: infinite;
14 -webkit-animation-direction: alternate;
15 }
16
17 #scene {
18 position: relative;
19 top: 60px;
20 text-align: center;
21 }
www.dbooks.org
2. Understanding the sample application 11
22
23 #words span {
24 border: 1px solid #ccc;
25 background: rgba(255,255,155,0.8);
26 text-align: center;
27 font-size: 30px;
28 -webkit-box-shadow: inset 0 0 40px rgba(0,0,0,0.4);
29 position: absolute;
30 }
31
32 #words span:nth-child(1) { left: 45%; top: 0px; }
33 #words span:nth-child(2) { left: 25%; top: 100px; }
34 #words span:nth-child(3) { left: 65%; top: 100px; }
35 #words span:nth-child(4) { left: 10%; top: 200px; }
36 #words span:nth-child(5) { left: 45%; top: 200px; }
37 #words span:nth-child(6) { left: 80%; top: 200px; }
For simplicity the File contains the styles in-line, but you can also define your CSS in a separate File.
Here we’ve defined the positions of the words, and the spinning animation. This is just standard
CSS. Later in the example you’ll see how the class ‘rotate’ is assigned to some elements to make
them spin. To try out this style-class just assign it to one of the Buttons. Place the cursor inside one
of the buttons and type “class=’rotate’”.
Note how NetBeans helps you by offering you the class in code-completion:
Enter archeype
Now preview the page again using right-click -> ‘View’. You will see the effect of adding this class:
The Button rotates.
also works in the opposite direction. We can define it so that e.g. entering a text in the input will
automatically update a bound property in the data model. The bindings are only defined in the view.
When we look at the datamodel later, you’ll see that it doesn’t have to reference the view at all. This
technique is known as the Model-View-ViewModel (MVVM) Pattern.
1 data-bind="textInput: message"
This means that the value of the input field is bound to the ‘message’ property of the datamodel. This
binding is bidirectional. When the datamodel’s message-Property changes, the input will update.
And when the user enters some text in the Textfield (and thus modifies the ‘value’-attribute), this
will update the datamodels ‘message’-Property.
www.dbooks.org
2. Understanding the sample application 13
The Model
In a ‘normal’ Knockout-Application the model-class referenced from the view is defined as
JavaScript. DukeScript changes that in order to make the application better maintainable, testable
and to leverage the superior tooling of Java.
Simple Properties
Let’s have a look at the DataModel now. It’s defined in the File ‘DataModel.java’. The package it sits
in depends on the Maven-Coordinates you entered during Project creation. You can find it in the
‘Source Packages’-Folder of the Project. The DataModel is annotated on class-level:
The ‘Model’-Annotation is evaluated at compile time. As a result a class is created. The name of this
class is defined via the ‘classname’-Attribute. In our case the classname is ‘Data’. In the Project-View
of NetBeans you can find the generated class ‘Data.java’ in ‘Generated Sources’. The benefit of this
approach is that you don’t need to write Setters or Getters for your Properties, or care about the
special requirements of a Model that works with Knockout. Instead you define the Properties via
the Annotations ‘properties’-Attribute. In our case there’s a Property ‘message’ of type String, and a
boolean-Property named ‘rotating’. We’ve already seen these two Properties in our View Definition.
Computed Properties
But the View also uses a Property called ‘words’.
This Property is not defined in the Annotation. The reason for this is, that the Array of Strings
returned from this method is computed by splitting the ‘message’-Property into single words. This
cannot be defined in a simple Annotation. Instead we wrote a static Method of that name that does
the computation. We annotated it with ‘@ComputedProperty’. So the value of the ‘words’-Property
referenced in the View is the String-Array returned from this method.
2. Understanding the sample application 14
The ‘Function’-Annotation
You already saw that the view also calls a couple of Methods of the Model. Like the ComputedProper-
ties these Methods are also defined as static Methods and annotated with ‘@Function’. The Method
‘turnAnimationOn’ simply sets the rotating-Property to ‘true’. So it becomes obvious now, how the
control flow works. The user clicks the Start-Button. This calls the Method ‘turnAnimationOn’. The
Method in turn changes the value of the ‘rotating’-Property:
As a result the CSS-class ‘rotate’ is added to the spans created from the words, and they start rotating.
What you’ve seen up to here is the basic usage of the APIs. The idea behind the framework is, that
a normal developer does not have to deal with JavaScript at all. But sometimes it’s required to
integrate other JavaScript functions. In the workflow we’ve developed for DukeScript this is part of
the role of API-Designers. There’s also an example of that in our demo application. Open the project
with a name ending in “JavaScript Libraries”. It contains a class that shows how we define an API
in DukeScript. The class Dialogs provides a way to invoke javascript functions from Java.
The ‘@JavaScriptBody’-Annotation
The @JavaScriptBody-Annotation makes it easy to execute JavaScript-Code. To use it you need to
define a static native Method. The Annotation has a parameter called ‘body’ which defines the
JavaScript to execute. The value returned from the Method call can either be a Java String or
primitive Type, or a JavaScript-Object. The Method ‘showScreenSize’ that we call from the view
in turn calls such a ‘native’ Method called ‘screenSize’. This Method returns a String which is
automatically converted to a Java String.
The @JavaScriptBody-Annotation also makes it easy to pass arguments to the JavaScript. This
is done via the ‘args’ parameter. The Method ‘confirmByUser’ takes a String and a Runnable as
arguments. You can see in the Annotation that these two Arguments are declared in the ‘args’-
Parameter of the Annotation. Like this we can use them in the JavaScript. In case of a Java Object,
www.dbooks.org
2. Understanding the sample application 15
we can even call it’s methods following a standardized syntax. This is how the Runnable is executed
from the confirmation Dialog. We’ll have a closer look at this syntax later. The @JavaScriptBody
Annotation makes calls to JavaScript typesafe for the caller and hides the JavaScript from ‘normal’
users. This makes applications maintainable and the Compiler can find Bugs at compiletime that
would otherwise occur at Runtime and require extensive testing.
The main method of this class creates the main Window using BrowserBuilder. What happens
behind the scenes here depends on the platform. The platform specific HTML-Renderer-Window is
created (newBrowser()) and loads the view using the loadPage method. With loadclass the Controller
is created, and with invoke we can define a Method to be invoked when the Page is loaded The
‘onPageLoad’-Method referenced here is responsible for creating the Model and initializing the
binding (applyBindings).
2. Understanding the sample application 16
Summary
This is how the example application works and how the parts play together. Now that you have a
basic understanding of the architecture of a typical DukeScript application and the Knockout API
for Java.
www.dbooks.org
4. Debugging a DukeScript application
You now know how to create a project and run an application. I’ve shown you how the application
works. Now it’s time to learn how to debug it. We’ll first have a look at how to debug the Java Code
of the application. Then we’ll have a look at visual Debugging using the NetBeans Inspector.
Let’s set a breakpoint now. Open the project “helloworld General Client Code” and in the DataModel
class look for the method turnAnimationOn. You can set a breakpoint by clicking in the grey bar
left of the editor.
Setting a breakpoint
If you click the start button of the application this function will be invoked and program execution
will stop at the breakpoint. In the Debugging window you can inspect the stack.
4. Debugging a DukeScript application 18
Stopped on breakpoint
The method takes an instance of Data as an argument. When hovering over the variable you can see
the content of the model as a JSON String. That’s because the toString method of the model class
automatically produces JSON.
If you click the little grey triangle to the left of the tooltip the window expands and you can further
inspect the content of the model object.
Inspecting Variables
You can now use the toolbar buttons or the keyboard shortcuts to “step over”, “step over expression”,
“step into”, “step out” like in any regular Java application. You can find a detailed guide on all the
www.dbooks.org
4. Debugging a DukeScript application 19
Don’t forget to save your change. The application will continue to run, but when you change the
input String all words will be in upper case. The cool thing is, that the application will not redeploy,
but keep it’s state. So you can develop your application while it’s running.
Visual Debugging
Now you know how to debug your ViewModel and hot swap code, but what about the View? When
developing in NetBeans debugging the view is very simple and comfortable. When you run the
application you’ll see a couple of Tabs pop up. One of them is labeled “Browser DOM”. This tab shows
the live DOM tree of the running application. Select an Element there and it will be highlighted in
the running application.
⁶https://netbeans.org/project_downloads/usersguide/nbfieldguide/Chapter5-Debugging.pdf
4. Debugging a DukeScript application 20
On the top left of the “Browser DOM”-tab there is a little button (dashed rectangle) that starts the
“Inspect Mode” in the Browser. If you activate it, you can mouse over the elements in the browser
and they will be highlighted and also selected in the DOM tree. There’s a useful little tooltip showing
the size of the element.
But there’s more. Another new tab that was opened when launching the application is the “CSS-
Styles” tab. It will show all relevant CSS style attributes of our project and where they come from.
Try it out and select the word “Hello” (which is a span element).
On top of the “CSS-Styles” tab you’ll find the properties of the span. You can see the current value of
the property, for example the property top has a value of 0px for the word “Hello”. The context menu
of this property has the action “Go to Source” which will open index.html at the position where the
inline styles are defined. You can now edit the HTML-file and change this value to 100px. When you
save this change, the UI will update, and the Span will be relocated.
www.dbooks.org
4. Debugging a DukeScript application 21
You can do a lot more things with this little subwindow in the tab, for example show the properties
for different pseudo classes (states) of your element or inspect the stylesheet hierarchy.
In the middle pane you can see the applied styles listed by name, and you can jump directly to the
CSS-File where they are defined (or in our case to the html file).
The lower pane displays all the properties of the style class that is currently selected in the middle
pane. You can also remove or change a property or add a new one. You will even get a list of all the
properties relevant for this element.
Knockout Tab
Another tab is labeled “Knockout”. It shows you the knockout context of the active element. This is
really useful to analyze where you are in your viewmodel hierarchy, especially when using deeply
nested viewmodels.
The value for “$data” shows you the current context. If you select the body, or the input element,
you can see the current context is the full Data model. It is displayed as “JavaRuntimeObject”, and
you can see it’s Properties and functions.
If you select the “Hello”-Span instead, the context is “Hello”. That is because you’re inside the
“forEach” loop now, and the context of each element is one member of the “words” array.
You can also see that it’s $parent is an array, and that the $root context is our full Data instance.
The property names $root and $parent are also the names you can use in the data binding to access
the parent or the root model. This is important if you want to call a method on them from a nested
level. You’ll learn more about the scope of knockout viewmodels and their scope in the next chapter.
Device sizes
If you launch the application from NetBeans, there’s a toolbar on top. You can use this toolbar to
test your UI at various device sizes.
www.dbooks.org
4. Debugging a DukeScript application 23
If you invoke it, the build will look for attached devices. It will print a message when your device
was found and launch the application in debug mode. Now you can set breakpoints like in a desktop
app.
You can also use an emulated device instead. Just use the android AVD manager to create and/or
start the virtual device. Then invoke the debug action. It will work exactly the same, but it takes a
bit longer. On the lab computers, there’s already a predefined device.
Use the File Explorer to navigate to “C:/Program Files(x86)/Android/Android SDK”. Double-click
the SDK Manager.exe file.
In the Menu, go to “Tools” and select “Manage AVDs”. Now select the device “nex4” and afterwards
click the start button. Please wait until the device is fully booted before you continue with the task.
Locate the method “testCallbackFromJavaScript” and set a breakpoint on the line where the “called”
counter is increased inside the Runnable. Then rightclick the test and from the context menu execute
“Debug Test File”.
The test will stop at our breakpoint as expected. Now have a look at the call stack. You should find
a stack element that has “eval” in it. To locate it you can hover over the stack elements and find the
frame that has “jdk.nashorn.internal.scripts.Script” in it.
⁷http://docs.oracle.com/javase/8/docs/api/javax/script/package-summary.html
www.dbooks.org
4. Debugging a DukeScript application 25
JavaScript Debugging
You can now mouse over the elements, and you will see the values of the variables. In the screenshot
above you can see the value of the “msg” variable coming from the Java call. The method we have
here is rather short, but if you have a longer method, you can also set breakpoints and step through
the execution just like in a Java file.
So not only can you debug the nice and clean Java code you write, but even the otherwise hidden
“native” calls under the hood.
Summary
In this Exerceise you’ve learned how to debug all the aspects of a DukeScript application. We’ve
inspected the Java code and did hot swapping while keeping the state of the application intact. We
changed the appearance of the application while it was running and inspected the Dom and CSS.
You’ve learned how to debug an Application on Android or iOS devices or in the emulator. And we
had a look what is required to debug JavaScript code.
Testing
In this part of the lab you’ll learn how to write unit tests for the ViewModel of your application.
This allows you to test the view logic, even before you write the view.
www.dbooks.org
Testing 27
In DukeScript we’re using a Model View ViewModel⁸ (MVVM) architecture. This has a lot of is
perfect for Test Driven Development.
You simply start by writing a unit test for the ViewModel. Then you create the ViewModel class (if
it doesn’t exist yet) and implement the functionality to pass the test. Since the ViewModel knows
nothing about the View, there’s no need to bother implementing the View yet. You can perfectly test
your UI without it. You can test the pure functionality. As a result your test code and the ViewModel
itself will be very concise.
⁸http://en.wikipedia.org/wiki/Model_View_ViewModel
Testing 28
Wizard Step 2
In the next Wizard page choose a name (“DataModelTest”) and a base package, and click finish.
www.dbooks.org
Testing 29
Wizard Step 2
The generated class will open in the Editor, add the following Test method:
Now we need to write the ViewModel that passes this test. Create a new class named “TodoListView-
ModelDefinition” and add a Model Annotation like this. The addEnabled method is a Computed-
Property⁹, just like the “words” property in our first exercise. It depends on the inputText Property
and automatically will be reevaluated if the inputText changes:
⁹http://bits.netbeans.org/html4j/1.1/net/java/html/json/ComputedProperty.html
Testing 30
Execute the test, it should pass. That was fairly simple. We can skip the refactoring step, because the
code looks OK. Ready for iteration two. Let’s write another test. This time we test if the “add”-button
does it’s job:
1 @Test
2 public void addButtonAdd() {
3 TodoListViewModel model = new TodoListViewModel();
4 assertEquals(model.getTodos().size(), 0);
5 model.setInputText("bu");
6 model.addTodo();
7 assertEquals(model.getTodos().size(), 0);
8 model.setInputText("buy milk");
9 model.addTodo();
10 assertEquals(model.getTodos().size(), 1);
11 assertEquals("", model.getInputText());
12 }
Now lets alter the ViewModel to also pass this test. The @ModelOperation¹⁰ annotation used here
ensures that we can call our method from any Thread, which simplifies the Testing:
¹⁰http://bits.netbeans.org/html4j/1.1/net/java/html/json/ModelOperation.html
www.dbooks.org
Testing 31
10 }
11
12 @Function
13 @ModelOperation
14 public static void addTodo(TodoListViewModel model) {
15 if (model.getInputText() != null && model.getInputText().length() > 2) {
16 model.getTodos().add(model.getInputText());
17 model.setInputText("");
18 }
19 }
20
21 }
Perfect all our tests pass. The “add”-function works. But the code is not nice. There’s a duplication
for validating the input. We could check for isAddEnabled, but that would be ugly. First we might
decide to add new entries via a different channel, and second the method name should reflect the
purpose of the method. So let’s refactor it:
25
26 }
Now it’s time for the “delete”-button. We’ll first test if it’s correctly enabled and disabled:
1 @Test
2 public void deleteButtonEnabled() {
3 TodoListViewModel model = new TodoListViewModel();
4 assertFalse(model.isDeleteEnabled());
5 model.add("buy milk");
6 model.getSelected().add("buy milk");
7 assertTrue(model.isDeleteEnabled());
8 }
www.dbooks.org
Testing 33
The code looks OK, no refactoring required. And finally we’ll test if pressing the delete-button really
removes the item from the list:
1 @Test
2 public void deleteButtonDelete() {
3 TodoListViewModel model = new TodoListViewModel();
4 model.getTodos().add("buy Milk");
5 assertEquals(model.getTodos().size(), 1);
6 model.getSelected().add("buy Milk");
7 model.deleteTodo();
8 assertEquals(model.getTodos().size(), 0);
9 assertEquals(model.getSelected().size(), 0);
10 }
1 @Function
2 @ModelOperation
3 public static void deleteTodo(TodoListViewModel model) {
4 List<String> selected = model.getSelected();
5 for (String selected1 : selected) {
6 model.getTodos().remove(selected1);
7 }
8 model.getSelected().clear();
9 }
Done, all the tests pass, our ViewModel works. Now we can start developing the View part:
Testing 34
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Todo List</title>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6 </head>
7 <body>
8 <input data-bind="textInput: inputText" />
9 <button data-bind="enable: addEnabled, click: addTodo">add</button><br>
10 <select style="width: 100%" size=10 data-bind="foreach: todos, selectedO\
11 ptions: selected">
12 <option data-bind="value: $data, text:$data"></option>
13 </select>
14 <button data-bind="enable: deleteEnabled, click: deleteTodo">delete</but\
15 ton>
16
17 </body>
18 </html>
All the bindings are declarative and simple. They don’t have complex binding logic. That is an
important part. If we start writing complex bindings, we will often unintentionally put UI logic into
the View where it is hidden from our test, and we’ll loose the benefits of TDD. But with simple
bindings like in this case there’s not much that can go wrong.
Obviously there is some cheating involved in this process ;-). I sometimes add the required
Properties just before I write the test. That prevents unnecessary little bugs and typos like writing
“getEnabled()” instead of “isEnabled()”. But generally I like to write the test as a way to design the
API. It forces me to take the API user perspective. That helps to design an API that is clean and
simple.
You can also checkout this project on Github¹¹.
Summary
In this part of the lab you’ve learned everything you need to create an application with excellent
code coverage which will make your boss and your customers happy. That’s a nice side effect. But
most importantly, you’ve seen how DukeScript makes it really simple to unit test most aspects of the
application by using the MVVM pattern. Using these test patterns you’ll be able to create applications
that are easy to refactor, because everything is tested. And they are easy to understand as well,
because unit tests are a great way of documenting how your APIs are used.
¹¹https://github.com/dukescript/tdd-example
www.dbooks.org
Testing 35
This is the last part of this lab. To learn more about DukeScript, please check out our Blog¹² and
website¹³. Thanks for participating in this lab, and enjoy JavaONE!
¹²https://dukescript.com/blog.html
¹³https://dukescript.com