021 AiA Duck Angular with Avishek Sen Gupta

Download MP3

The crew talks Duck Angular with Avishek Sen Gupta.


**[Does your team need to master AngularJS? Oasis Digital offers Angular Boot Camp, a three-day, in-person workshop class for individuals or teams. Bring us to your site or send developers to ours --  AngularBootCamp.com.]**CHUCK: Hey, everybody! Welcome to Episode 21 of the Adventures in Angular Show. This week on our panel, we have Joe Eames. JOE: Hey there! CHUCK: I'm Charles Max Wood from DevChat.tv. I just wanna give you a quick reminder to go check out JS Remote Conf, that’s at JSRemoteConf.com or you can text “JSRemoteConf” to 38470, and you'll get on our email list and might get a few updates as text from that. I'm probably just going to let you opt either way. We also have a special guest this week and that's… Avishek Sen Gupta. AVISHEK: Hi, everyone. CHUCK: I know I killed your name. I'm sorry. AVISHEK: No. It's all right. It's close enough. CHUCK: So do you wanna introduce yourself really quickly? AVISHEK: Yeah. So I've been programming for a long time. I actually work at ThoughtWorks. I've been working with them for ten years. And I have programmed on different platforms, .NET, Java, JavaScript, Ruby so on. So yeah, that's really it. CHUCK: Awesome. So you wrote this testing framework or I don't know if that's the right term for it, called “Duck Angular” to test Angular applications. AVISHEK: Yes. It's probably easier to kind of give you some context on why I wrote it if that's okay. CHUCK: Yeah, that would be helpful. AVISHEK: So it kind of started on one of the projects that we're working on which we are using Angular quite heavily and the team was kind of quite new to Angular. They started writing tests for it. At the beginning, they started using Selenium to do functional tests, running tests in a browser. What really happened was as the number of tests kind of grew in size as well as in number, the turnaround time for getting feedback on whether a functionality was broken or not became longer. People weren’t happy. The testing cycle was too long. And it is really the developers kind of wanted a simpler way to test Angular views and interactions without having to go all the way up to the top of the testing stack using functional tests. So that was basically the problem statement. So I was like, “All right, let me go and see what I can do about it.” And I knew that Angular basically exposes a lot of the functionality to compile views and attach controllers and so on and so forth. So I was like, “Why don't I kind of just take a view, load it up, compile it, and attach a controller to it and do all that without having to go inside the browser?” So that's really exactly what I did. And initially, it was pretty rough around the edges, but people seem to like it because it actually let them test views, as well as user interactions all in the context of a unit test. They were able to test parts of views much faster. And at one point I was like, “all right, maybe give it a name.” And I don't know why I actually gave it a name Duck Angular though. I think it was 4:00 am in the morning. I wasn’t thinking clearly. CHUCK:[Chuckles]**AVISHEK: But yeah, that was the name I gave it and the name stuck. And right now, it's in heavy use in a lot of the projects that I'm working on. CHUCK:**I have to say that I've used Selenium WebDriver and it is not fast. [Chuckles] Now, is that the system that Protractor uses, because it seems like Protractor is kind of the more popular… I don't know, official way to test your Angular apps.**AVISHEK: Yeah, sure. However, I think Protractor is at the same level as Selenium WebDriver. And what that basically allows you to do is actually open up a browser and kind of do whatever the user would do if he or she were interacting with an Angular app. Duck Angular actually allows testing at a lower level. So when I say “lower level,” I mean both from the point of view of the level of the test, which means that you're writing a unit test, and you are not really opening up a browser. You actually have the opportunity stub out dependencies if needed and you can actually test parts of views, so you don't necessarily need to bootstrap or set up the entire app to be able to test the parts that you're interested in. So, yeah, I would not want to compare Duck Angular and say, Protractor, because they allow testing at different levels. CHUCK: I think there's a place for both, but yeah it's really interesting to talk about that. Typically, when I'm writing unit tests, I'm using something like Jasmine or Mocha and then I'll use Sinon and stuff or some of my mocking, stubbing and spying.  Does this just add to that stack or is it a completely different stack from the Jasmine or whatever that you’d be using? AVISHEK: Right. So calling Duck Angular test framework is somewhat of a misnomer because it doesn’t replace Jasmine, Mocha, Sinon or any of those. In fact, you will definitely need to pick either Jasmine or Mocha and Sinon -- any of the normal testing libraries that you use or assertion libraries and so on. What Duck Angular itself loosely is more of a… I would like to call it a “helper library,” except that it's rather big helper library. What it facilitates is setting up your view. So for example, if you have a view called say view.html, right? And you have a controller called foo controller. What it essentially allows you to do is specify that you want to use view.html, you want to hook up foo controller and there are a bunch of dependencies that you might want to stub out because they make server calls or whatever. And after that, Duck basically just gives you few objects to inspect the DOM. The DOM which is kind of like in memory. And after that, you are basically when you're writing Duck Angular tests, all you’re really writing is either writing Mocha tests or Karma tests or whatever and you are asserting using Chai or whatever. Duck simply lets you set up your views and controllers so that you can actually go ahead and make those assertions. So yeah, it works seamlessly in conjunction with all the libraries that you're already using. JOE: Were you inspired at all by React? AVISHEK: Are you talking of React in terms of like the DOM, the in-memory… JOE: Yeah. AVISHEK: I did encounter React later, but my first realization that this could actually be done was when I actually was able to boot strap an Angular app to a DOM node -- which actually did not exist -- and the Angular bootstrapped perfectly well. And I was like, “Okay, that's interesting.” Which means that I don't actually need a real browser DOM to actually bootstrap an app, which means that the app is actually still in memory, everything is registered but you don't really need a visual component to get it to work. So that was my first realization. I saw React much later and it did talk of like the DOM and how it can… like shadow DOM and so on. But I don't think I specifically was inspired by React. JOE: Gotcha. So, was it all pretty shocking to you when you can get it to work that way? AVISHEK: Yeah. It was pretty interesting. I mean, there were several issues that I had to work out as well. So for example, there were a few things that I had to do to kind of allow nested views and so on and so forth. So initially, I was pretty shocked, as well as gratified. And then I was like, “Okay, let's see what are the boundaries of the way that we can test this.” I mean, it has reached a point at which, because the app that we're working on, or let’s just say the suite of apps that we're working on, it's actually quite a big Angular app and there are like multiple apps around, which means that it is actually impractical to get feedback from functional tests in a timely manner. So the QAs themselves have actually taken it upon themselves to rewrite large parts of the tests for the app in Duck Angular, for the parts which don't need to make server calls where you're just testing UI interactions, simply because it gives them much faster feedback and developers can kind of react to issues much quicker.  So I'm seeing a good uptake from the QA side of things as well in terms of using the framework. JOE: That's awesome. CHUCK: So it renders the HTML and then executes the JavaScript I'm assuming? And then you can verify that any DOM transformations or any other management of different aspects of your website are handled through Duck? AVISHEK: I think a lot of what Duck does, it kind of delegates to the Angular framework itself. So for example, Angular has the compile service, which essentially just takes a piece of string which is your view and the scope and binds it together and spits out the DOM. I mean, it's exposed by Angular and Duck simply kind of makes use of that to inject things that you might want to test really. So really, that's how it does. It kind of delegates most of its work through Angular. It doesn't do a lot of work by itself. All it really does is kind of provide a much nicer interface to kind of be able to like inspect the DOM and do all of that without actually rendering it in the browser. The other interesting thing is as a result of this, it also allows us to actually test user interactions. So for example, clicking a button, clicking a link, all of those things, what it really does is because it has access to the DOM -- the DOM in memory -- it essentially can fire  jQuery events on any of those DOM elements. And because Angular was allowed to bootstrap the app, firing those elements immediately fires off any of the controller functions that were hooked on to them.  So it's not just static view only testing that you can do, you can also test like user interactions and so on. So Duck provides a nice API, so that you don't have to like manually fire the events yourself and so on. CHUCK: So are there any limitations to Duck? Are there things that you should be testing  with something like WebDriver or one of the other libraries out there? AVISHEK: Yes. I think there is a very clear segregation of the kinds of things that I would want to test in Duck and the kind of things that I'd want to leave it up to Selenium and/or Protractor. So the things that I would not want to test using Duck is when you are actually moving across Angular routes. So if you are going like across pages and so on and so forth, really because I wanted Duck to allow people to test at a very low level parts of views and maybe views themselves, but not going across any entire app. So, things like that are probably better left to true end to end tests. The other thing that I would prefer to test using Protractor and/or Selenium is when we actually need to connect to server when we're actually making Ajax calls and so on and so forth because in most cases, the use case that I've seen for Duck in most cases is when you're just testing the view logic, the client side logic and not really worried about what is coming back from the server. But if you're really interested in knowing what is coming back from the server, that is more in the realm of the integration test and something that I would wanna test end to end anyways. So yeah, in some sense, there is a clear segregation of what I would want and not want test using Duck. CHUCK: I'm looking at the example here, you could just explain really quickly, how do I set up my page so that I can run my test against it? AVISHEK: All right. Are you looking at a specific site or are you looking at the documentation? CHUCK: I'm looking at the documentation and readme on the GitHub repository. AVISHEK: All right, so the first thing to basically notice, like different teams write Angular applications. They structure it differently. So for example, one team might not be using dependency management at all. They might just be including JavaScript in their page using script tags. Another team might be using, I don't know, RequireJS for example and so on. So a team structure apps differently, so Duck Angular is not really opinionated about how you should really structure you application. The only requirement for Duck is that you should have actually executed all your JavaScript before Duck is… before you can actually start using Duck to start your test. So whether you are requiring like an AMD module, or whether you're just in your Karma, you're just like specifying your Karma conf all your files, it's only up to you. But the only requirement is all your JavaScript should have at least executed, otherwise there would be no definitions for what the controllers are or what services are and so on. So that's the first prerequisite. And that's not something that I fully covered in the documentation because each team will have their own way of executing that JavaScript. So once you're done with that, one you have basically loaded up your JavaScript, at this point, you really are writing a Mocha test. So if you're looking at one example you really just say… you write a mocha test and inside… So there's a couple of ways to actually access  Duck; if you're using AMD modules, Duck can actually detect that you are using AMD and can define itself as modules, otherwise it can define itself as some global variables that you can essentially use. So once you have that, you can basically use some of those variables. So for example, there are these variables called Duck factory where you can inject your Angular variables and queue and jQuery and so on. And at the end of it, you really have an object called, well, in the example that I'm using, it's called “mother” because it kind of like creates objects so it's like an object mother. But what it really does is you just say mother.createmvc and you say specify the name of the controller, you specify the name of the view or the page if that's what you want.  And there are several other optional parameters after that where you can specify whether you’re injecting any dependencies which you are mocking out. If there are multiple controllers involved in your view, there is a slightly different syntax that you can specify for your dependencies. And after that, so the Duck uses Promise’s syntax pretty heavily. It uses queue. And once it has basically, it has gotten the controller and the view and so on, it will basically wire all of them up and ultimately give you an object. It's called an MVC, but really all it has is MVC.view is your, what's should I say, it's the DOM really. MVC.scope is the scope which is attached to the view, and I think it has the MVC.controller which is the top level controller. After that, at this point, you're free to perform any assertions on the DOM at that point, or you can actually perform any UI interactions. If you wanna do UI interactions, you just create a UI interaction object and interact with using any sort of your standard CSS selector syntax and so on. So yeah, that's really it. I mean, if you kind of notice, Duck itself does not take over doing assertions or the way you write the tests and so on, all it really does is kind of give you helper methods to kind of access your DOM or fire events on it and so on. JOE: So I imagine while you're building this, you learned a ton of stuff about DOM interaction and about Angular itself. Is there anything particularly stand up as things you were surprised by or things that you thought were cool that you learned? AVISHEK:**Yeah. I think there are a couple of things which I’ve found out and was really happy about. So of course, I had to go through the Angular source and I still read the Angular source a lot because there are a lot of things that I assumed happen in one way and when you look at the source, you find that it's being done in a completely different way. But the one thing which is really useful is AngularJS publishes events for almost any sort of action which is being taken. So for example, I give you a quick example, I was trying to figure out how to make sure that if you had like nested views, so views inside views and so on and so forth because Angular loads those views asynchronously, if you actually start your test before Angular has resolved all the views and so on, you might actually get like null references  and so on. So I really needed to know how many nested views were actually being loaded. And it turns out that every time a view was loaded, Angular publishes an event called… I can’t exactly remember. It's called view content loader or something, and really, because of the number of events which are basically [?] from Angular, it's very easy to kind of get a sense of what is happening at any given point in time during the digest cycle of Angular. So that's one thing I think was a really smart thing which happens inside the Angular code base, which also makes it easy to understand what is really going on and what the sequence of events. So that's something really interesting. The other thing I kind of found out which was pretty useful of course was the fact that Angular caches its templates. So this is another example where when you're actually testing directives in Duck Angular, sometimes the port of the template URLs don't actually match the templating URL that you really want to load. And in those cases, because you're running in Karma and it's serving from a different port, it can’t really load those templates. So because it kind of exposes a lot of its internals, so right from compiling a template to getting an API to let you cache those templates and so on, all of those things because it exposes those internals, that I think kind of made Duck Angular possible. It's not like closed off or it's not cryptic or it's not like marked as “here be dragons, don't use this.” So I think those were things which I've found were really interesting in the Angular code base.**JOE: Did you find any dragons in the Angular code base? AVISHEK:Well, yeah [chuckles] the only dragons I did find in the Angular code base were the things which… well, they were about… I don't know. I don't think I remember any specific ones at this point. There weren’t any at this point, yeah.JOE: Did it feel like you were building a whole framework when you built Duck Angular? AVISHEK: It started out as pretty small. It was barely a hundred lines of code when I first started. At this point, it is around 614 lines. So it has grown. It has grown kind of organically. Like I didn’t specifically had a clear road map of where I wanted it to end up, but invariably, as people start using it more and more, they were like, “Hey, there's this functionality of this functionality that I would really want to test and Duck doesn’t give me an easy way to test it.” And I'm like, “Okay.” I mean, initially, I would actually work to kind of get that functionality in, but very soon, people started contributing quite a bit, so that they could get their favorite functionality into it. So yeah, it's growing, but it's not like by leaps and bounds. At this point, I would kind of consider it to be stable enough for use in large teams, given that large teams -- at least at the place where I work -- are already using it. CHUCK: I'm wondering is there… I guess this is more of a question about the tools you’re using, but I keep thinking to myself, “Man, it’d sure be nice if I can use something like Karma and have it run on the command line just  on NodeJS or something instead of having to load up a DOM or whatever.” Because I'm much more familiar with Jasmine. Jasmine at least, by default, wants you to open a browser window that executes all of your tests. And so, it would be nice if I could do that and have it run neatly in a little CI machine or something. AVISHEK: That is exactly what we do, Charles. We have at this point, around twelve hundred JavaScript unit tests; around six hundred or seven hundreds of them use Duck Angular and they all run from the command line. We actually use Karma with Mocha as the unit testing framework. Karma is the unit test runner. And all we really do is write from the command line and it spits out a JavaScript test report. And we actually run it as part of our CI pipeline as well, so yeah, that’s how we do it. CHUCK: Is there somewhere where I can see how you have that all set up? AVISHEK: Well, it is inside a network, so it's not publicly available to the outside world at this point, but I'd be happy to share more details of how we went ahead with our scripts and so on and so forth, offline if you want. CHUCK: Yeah. That would be cool and maybe we can set up some kind of like Google Hangout and just record it, so that you can help me set something up on another project somewhere. AVISHEK: Oh yeah, sure. I'd be glad to help. JOE: So where do you plan to take it from here? AVISHEK: I plan to introduce it to more projects because there are an increasing number of projects which are using Angular. And I kind of hear from grapevine that more and more of that… that they are saddled with functional tests and their feedback times are getting longer and so on. Initially, people are somewhat skeptical of, “Okay, what is this framework? I have heard this before, and why can’t I just write  a functional test?” But the reality is as applications grow, the number of test case scenarios and so on keep on growing and people at some point will always want to look for alternatives. I am not whether I would actually go ahead and rewrite Duck when Angular 2.0 comes out, because it changes a lot of things, but maybe Angular 2.0 might have something like that built in. I don't know at this point. But at this point, I do intend to kind of evangelize it and have teams atleast try it out. One of the biggest things that I've seen in problems in the adoption of Duck, is because it is not very opinionated, teams kind of have to set up a little bit of initial scaffolding and set up in order to kind of get started writing Duck tests. And that sometimes puts people off but that is kind of like a onetime cost. And once people see the value of the tests, they eagerly start writing more. So in terms of roadmap, I don't intend to cover each and every special case which teams do come up. I mean, there was this team which was using a mark down editor as part of their Angular application and they were like, “We want to be able to test the markdown editor and a Duck Angular test as well.” And I was like, “We can build it, but do you think that effort is worth it, or would it be better if we just went ahead and wrote a functional test for it?” So, there are some things that I've decided are not worth supporting  in Duck, but ultimately, it's always a dialog between people who want to use it and myself. JOE: Right. CHUCK:If I wanna start using the tool, what are some of the best ways for me to get started with it? Because I mean, on the show we have about a half hour and so we really kind of scratched the surface and encourage people to go check it out on their own. So where do people go to check it out on their own? The easiest way to kind of use it and to kind of just like drop it and play around with the library itself would actually be checking out… I actually have an AngularJS seed application which uses Duck, which has a link that I can share later, which actually uses Duck, so they can kind of just download it and host it off a local server, just run the tests. That one has, I think it uses both karma as well… yeah, it uses Karma and Jasmine. It has two branches for both variants. So they can basically start playing with it that way as well.  If they want to use Duck Angular in their own application, it should be fairly simple too basically set up. If there are problems, they can always create an issue on the Duck Angular GitHub page. But the easiest way to get started with playing it is just downloading the sample application. [Dog barking]CHUCK:[Chuckles] We have a guest dog on the show.AVISHEK:[Chuckles]CHUCK: All right, well, we're pretty much out of time, so let’s go ahead and do the picks. Joe, do you have some picks for us? Or a pick and a tip? JOE: I do. I'm going to pick the book, Resonate by Nancy Duarte which is a book about giving presentations, especially PowerPoint, that sort of thing. It's a really great book. It talks basically about how to resonate with your audience, how to connect with them. It's an awesome book. I really enjoyed it. Followed a lot with what she said. Really agree with what she said. So great book. If you happen to give presentations at all, I highly recommend that you pick it up and read it. Great book. And for my tip, my tip is going to be to check out Firebase. Firebase is awesome! AVISHEK: All right, my tip is this website called Rands in Repose. It’s really an awesome blog by an engineering manager. Talks a lot about people dynamics and you know working with the different departments in the IT organization and so on and so forth, because we are developers and sometimes we might be too closeted within our own world, but there are entire groups of people who sometimes we have to interact with. And this kind of talks a lot about what goes on in those circles and how to interact with them. So, that would be my pick. CHUCK: Very nice. I'm going to pick a video. This is something that I've been using to get stuff done and things like that. Basically, what happened was I set some goals for the rest of this year and then I took it by mastermind group. And you can actually watch the mastermind group every week on entreprogrammers.com. But anyway, so I took it to the mastermind group, and I got some feedback from those guys. And part of the feedback was a video done by John Sonmez on how he plans out his week. And it is really good. So I'm going to go ahead and pick that video. It's like five minutes long and it basically just outlines how to plan out your week. He uses a tool called Kanban Flow, which is actually a Kanban board but the way he uses it is a little bit different and I've kind of tweaked it for my own stuff. So yeah, that's my pick and go check out JS Remote Conf. We'll wrap this up. Thanks for coming. AVISHEK: Thank you for having me. CHUCK: We'll catch you all next week! [This episode is sponsored by Mad Glory. You’ve been building software for a long time and sometimes it gets a little overwhelming; work piles up, hiring sucks, and it's hard to get projects out the door. Check out Mad Glory. They are a small shop with experience shipping big products. They're smart, dedicated, will augment your team, and work as hard as you do. Find them online at madglory.com or on Twitter at @madglory.]**[Hosting and bandwidth provided by The Blue Box Group. Check them out at bluebox.net]**[Bandwidth for this segment is provided by Cache Fly, the world’s fastest CDN. Deliver your content fast with Cache Fly. Visit cachefly.com to learn more.]**[Do you wanna have conversations with the Adventures in Angular crew and their guests? Do you wanna support the show? Now you can. Go to adventuresinangular.com/forum and sign up today!]

Sign up for the Newsletter

Join our newsletter and get updates in your inbox. We won’t spam you and we respect your privacy.