 So, what's your expectation from this talk or this demo? Blank means nothing, which means I can, I'm done, right? No expectation already fulfilled, easy to leave. So test-driven development for front-end code is one expectation, okay? That's the next section right after me that continues, but I'll give you a quick demo, yeah. It's also very hard, okay? How many people here are practicing test-driven development at work today? Okay? And so for those who are practicing, you're looking for how to do this in front-end code, but I saw about five hands go up. What about the rest of them? Okay? That's the wrong talk then. This talk is not going to focus on that aspect. That's a much broader topic. This is more focused on test-driven development of front-end code. More broader stuff, I'm not sure if we'll be able to cover in this talk, but if many people have that question, we can change the talk and focus on that. All right. Let me get off, get started and we will see as we progress what needs to be done. So this demo is about test-driving front-end code and specifically I'm going to use React.js, which is something that Facebook launched about a couple of years ago, maybe not two years, little less. But before we jump into this, I want to touch a little bit upon object-oriented programming. How many people are here practicing object-oriented programming? Cool? My secret agenda is to actually convince you to do functional programming as part of this demo. Does everyone believe that O is about modeling real world? Thank you. You will be surprised because that's absolutely the wrong thing to do because soon you end up with things like this and like this. Anyone has class diagrams that look like this? Yeah? It may be much more complicated. So I used to work for Siemens Medical and we had this nice debate at one point. We spent about four hours debating on this topic. We were trying to figure out that we had a patient object. We had a doctor object and now there was this use case where the patient gets a shot, some kind of a vaccination. And so we had this debate about should the doctor have a method called give shot or should the patient have a method called get shot? Where would you put this method? You didn't answer my question. Where would you put this method? It's a separate object. What would you call that object? That's not a noun that cannot be an object. Treatment object. So you have a treatment object and you put this on the treatment. It's not really a treatment. I mean, it's a vaccination but you can get other shots as well. The point I'm trying to make is when you try to model software on real world, it's a complete disaster. The point of software is to actually abstract the real world, not model the real world. And this is where I think we all go really wrong and O gets really bad name. And that's when we say, you know what, O is almost dead. Let's kind of focus on functional programming because that's really where the future is. And so my hidden agenda is to actually kind of show you more of functional style of programming and using test driven development to do that. It's because one project does that doesn't mean anything, right? If you look at the vast majority of the new projects that are coming out, at least in the JavaScript world, a lot of them are using the functional style of programming to be more functional, right? To do more functional, actually, it's all hidden agenda to get the old O programmers feel comfortable, but a lot of it is actually behind the scenes functional. Anyway, that's not the point of this topic. Come to the functional programming conference. That was my plug for the conference. Come to the functional programming conference to really understand what the difference is. It's a day and night difference in my opinion. And take my word, five years from now, O wouldn't exist, as it not in the mainstream functional programming would take over. Anyway, our agenda today is to basically not 120 minutes, but 90 minutes. We're going to basically have a quick demo of test driving components, react components, using, I'm going to be using WebStorm, NPM, Jasmine, Karma, these are some of the tools that we'll use. What we're trying to basically do is build this thing out. This is from ConfinGen. If you've used ConfinGen, you can go in. There's a proposal on each proposal. You can add comments and stuff like that. So basically, we are going to try and build this out. You can have nested comments. You can reply to comments. You can edit comments. You can like comments. And you like comments, things move up and down based on the number of likes, and so forth. So this is kind of the component that we try and build today in the next 90 minutes. Let's quickly step back and talk about test driven development just so we are all on the same page of what test driven development is. So what's the idea of a test driven development? If you write the test which fails and then you write function, you write code. It could be functions. It could be methods. Test as you develop is too broad, but as she said, you write. Do you write all the tests or one test at a time? One test at a time. Do you have a design beforehand? But do you have a design to start with? Not necessary, right? So let's quickly look at this. So given a problem definition, we're going to start with a failing automated tests, all right? This could be a unit test. This could be a workflow test. This could be a end-to-end test. This could be any level of test. TDD itself does not say what level of test it should be. A lot of people misunderstand that TDD means write a unit test. That's a misconception that that's not true. So you write a test. When you run the test, what do you expect to see? No code is there, so it wouldn't even probably, you know, it would just throw runtime errors, right? Or it would throw compile time errors depending on if you're using a statically typed language. But what happens if the test passes? Absolutely. Be suspicious. Something's wrong. It ain't going to pass, right? It's not supposed to pass. So ideally, the test should fail. Then you make a little change to the code, right? What do we mean by little? In terms of is it days worth of work? It's seconds or minutes worth of work, right? That's what we mean by little change to the code. And then when you run the test, if it fails, you continue to make the change till the code passes, till the test passes. And then what do you do? You go back and repeat the cycle, yeah? And then three months later, you'll come back and say, this TDD thing is total crap. It doesn't work. Why? Don't take a picture yet. This thing is not completed. There's one more important step that is missing. Without this, if you practice test-driven development, it's going to be a total disaster. So whenever you have passing tests so far, you have not really done any real design design in that sense, right? So now's your time to actually do not upfront design, but rather responsive design or reactive design, right? Is you have some code, you're saying, OK, I've written the code in the best way I can. But now let me look at, is there scope for making the code even better? Are there any design principles I'm violating? Are there any patterns I could put to use? Are there any simplifications I can do to the code? So that's when we basically refactor, and we always refactor when we have passing tests, right? Why? Because you want to know that your refactoring didn't actually break any functionality, right? So that's why you want to run this whenever the tests are passing, refactor whenever the tests are passing. And that's when you go back and repeat this cycle, right? One test at a time, you go through this cycle over and over again, right? So if you want to take a picture, now that's complete, all right? Everyone's cool with this, refactoring becomes, OK? So you're saying that if someone's fresh out of college and you give them TDD, then they wouldn't know, they wouldn't follow a lot of the standard coding conventions and things like that. So that's the answer, right? Train them. When you, I don't know how, some people raise their hands when they put up TDD, right? How many people are practicing TDD in your company? How long did it take for you guys to get comfortable? All the nonsense they have learned over the years, and then get back into the practice of doing it in the right way, right? Because this is a fundamental shift in how we're going to be development. So it's not just freshers. Freshers actually pick it up very easily. It's actually the experienced people who have a lot of challenge with this because they have to unlearn a lot of their thing. Like the mind runs, right? You already know this is the design. You already think of all of that stuff. You have to stop yourself back and do it in a different way. So we will see in the demo as we go through till this thing comes up. So what we were talking is, let's wait for the slides to come up. But what we were talking before this is that it takes a good, at least a year before people can get good at this, right? This is why I think 99.99999% of the companies don't do TDD. Because it's a significant investment in terms of learning how to do things. And there are lots of misconceptions about TDD. And that's one of the big problems. I actually wrote a paper called Avtars of Test Driven Development in which I kind of captured lots of different styles of doing test-driven development. So test-driven development is not just one thing. There are many different styles of doing test-driven development. And this is why it takes time. So there's only one gentleman with the laptop. Nobody else has a laptop. But if you want to follow along, this project is on GitHub. You can go ahead, clone the project. I've done these steps already, but I'll kind of quickly run through this. So you do NPM update once you've got the project cloned. You might need Karma command line thing to be installed. So you simply do NPM install global Karma CLI. And then we're gonna do Karma init, which is, I'm gonna show you how to do this now. And then from there, we'll go and create a Jasmine spec to create our tests and run from there. And we'll see how we can use the Jasmine spec via the test runner. I've done this many times before, so it is all available online. So that was a good time to talk about myself before we jump into the actual material, right? So my name is Nareesh. I live in Mumbai. I was a partner at a company called Industrial Logic. We built the first e-learning. A lot of people at Google and other companies use our e-learning to train their developers on some of these skills, design patterns, test-driven development. Then I started another company called Adventure Labs where we build games for kids to learn mental mathematics. I've run a bunch of conferences, started the agile movement here in India back in 2004 and been running the conferences since. We run a bunch of other conferences as well. Right now, another startup that I'm working on is Convention, which is the platform that we're using to run the conference. And as of now, I'm helping hike with their product development, both the engineering and product management. So that's kind of a quick overview of who I am. Let's talk about what features this plugin is gonna have, this component that we wanna build, what features it's gonna have. Simple thing is it should basically accept a JSON and display the comments, right? So you give a JSON of comments, it should accept that and display the comments. Should be able to display the most popular comments on the top. That's the comments with the most likes on the top. If two comments have the same likes, then what do we do? We look at the one which was the most recent one, right? And we show that on the top. We also have a facility of having private comments. So the private comments is only visible to the person who's putting the comment and the program committee. No one else can see those comments, right? Should be able to like other people's comments and so on. So those are basically some of the features we'll try and cover today. Ready? Time to, so this is a good time if you get scared seeing code on the screen, this is a good time to leave the room. Let's hope this works. If not, we are in trouble. Let's look. Okay. So here's our basic code that we have. Everyone can see the code? All we have is just, I've written a Jasmine spec file, which says basically comments widget and we're saying it should display a nice message when no comments are present. Nothing else is done inside this and there's some stuff that is required by React to basically run these in test mode. And then we have basically an empty component. As of now, all it does is it gives a div. It spits out a div. So we're gonna get started right from the scratch. The first step, as we were saying, is we're gonna do karma in it. And it says which, basically which framework do you wanna use? We're gonna use Jasmine. It says, do you want require.js? No. Then it says what browsers you wanna test this on? So I'm gonna use Chrome. I'm gonna use Firefox. I'm gonna use Safari. That should be good for now. It says what is the location where you have your source files kept? So in our case, we have lib slash star star slash star.js. Then we have SCR, which is our source folder, slash star star slash star.js basically means include all JS files in the subdirectories inside this. And then finally we have the spec folder where we have all our spec and those are the files we wanna pick up. So those are all the files. Do you want to exclude any file? Do you wanna actually include any patterns? No. Do you wanna exclude any files? Do you wanna change the runner? No. We are gonna run that from within web storm so we don't need this being run outside. So what this would have done is this would have created a karma config file for you, which basically has the basic what framework you're gonna use, where are the files, what files are excluded, what preprocessors you need, and other information, what browsers you're gonna use and so forth. So in our case, we need a little bit more complicated stuff than this. So I'm just gonna take this for now, put it here and I'll explain you what's changed. We are excluding the standard react libraries that come in, we don't need them. We are, because we are using the JSX in case of React, so we are actually adding the preprocessor for React JSX. And that's, yeah, those are the only two changes, yeah. There is CSS files, so we are including the CSS files inside this so we can see how it looks. That's pretty much it, there is Jasmine jQuery, so I'm gonna be using a bit of jQuery to test things from my code and Jasmine itself. So that's pretty much all the setup we need for now. Let's come back to our component over here. If I run this, what it does is basically starts the browsers for you. So you see it started all the three browsers for me over here, yeah. It's basically listening to stuff on each of these browsers and then when we go back here, it says expected true to be false because that's what we have right now. So we have just the basic placeholder, we know the framework, everything is set in place and we are good to go, right? So what's the first test we are gonna write here? I've already kind of given you a hint, right? We're gonna start with, should display a nice message when no comments are present. That's the very simple, the most basic stuff that we can do and that can help us get started in some sense in terms of what we want to do, right? So we're gonna say var comments equals, we need comments component, but this needs to be rendered. So this is our comments component, but we need to render this comment component inside here. So that gives us a handle to the whatever, whenever the comments component is rendered on the webpage, this guy is gonna give us a handle to it. That's basically using test util, we are saying render into document, we're giving the component to it, it gives us the component, we are pulling out the DOM node from it and then we are wrapping it in jQuery and we are taking that back. So now we have a DOM handle to the particular component that's gonna get rendered right now, there's nothing. So it's not gonna give you anything, but that's what we're gonna build. Right, and the next thing we're gonna say is basically expect, what do I expect? I expect that the comments component, basically, what does it have? What do I expect back from this, right? We are designing what we want in terms of what the comments component is gonna give us back, right? So we're saying to contain an element, what element should it contain? We're saying div.mt, this is the element it should contain when this component gets rendered without any comments that we have passed, right? Now there's no way to pass the comments, so we are saying that it should render this and then we're also saying comments.findthisguy, which is the div.mt and this should contain text. What should it show? Be the first person to comment, something like that, right? We expect this kind of a message to be shown. Let's run this guy and sure enough it says it failed, it says expected to contain element div.mt, right? But right now our component doesn't spit anything, so that's why our test is failing. So what do we do to make this work? Is this a good first step to take? Is this a good first step to take? I need feedback, else I don't know what I am doing. If people have doubts, stop me, ask me so that we can make sense and move on, right? So I need feedback. Is this a first good step to take? Perfect, maybe not, but we'll see, all right? So we'll come here to our react component, right? What do we want now our react component to return? We want this guy to basically return, empty, and we are saying, what was it? Be the first person to comment, all right? Woohoo, that got us the first test passing. No black magic, right? It's just very simple stuff. This is a very simple stuff to get started. We know things are hooked up and no comments are passed. We will get this empty thing showing up, right? What's the next test we wanna write? Should display, single comment, nicely formatted. So how do we tell, how do we pass the comments, right? So we're gonna say comments equals, not this thing, and we're gonna pass a JSON to it, right? Like we said, this basically component takes a JSON. The JSON code, later we will extend this to just use HX and get the JSON from the server. For now we're just gonna feed the JSON to it, right? So you have a JSON that is being passed in, an array of JSON, right? Because you could have many comments that are being passed in from the server. So what does our array of JSON contain? First thing it might contain is, what does it need? It needs an ID, yeah? What else does it need? Commenters name, let's say user, and the actual comment, right? So we have an array of one comment, one JSON comment object that is being passed back from the server and we are feeding that into this guy and we expect that to come here. I've put it in the wrong place. This guy is empty, oh no, sorry, that was correct. Here we need to put this empty, right? The previous one that we had, we are saying that the comments is actually empty, no comments were passed. The second one we are saying is, should display a single comment nicely formatted and that basically is the comment that you've got back. Now what do you expect here? Should it still be an empty div? This should be some kind of a commenced div, yeah? So you should get a commenced div, but also more importantly, what do you want? You also want to make sure that one element is present inside this, right? So we're gonna say this guy dot, what do we say? Length to be one. So we're saying this comments should contain one element within it because we've sent one comment and then we're gonna say that comments dot this, div dot comment header should contain text, what? Header should contain, let's say, the name of the person who's done this and then the body should contain the first comment. I'm trying to structure my elements, right? So that we can then do nice formatting and all of that stuff. And so basically what we are trying to do is we are saying if one element was passed, then the length of the comments should be one and then that should contain again another div which basically has the header set to the person who put the comment and the body should be the first comment. Let's go back here and look at what are, that's the UI. This thing, right? We're just trying to put this guy out here and then the body is inside here. So the header is one styled in a different way and the body is styled in a different way. So that's kind of what we are trying to achieve here. Clear so far? Does this make sense? Now what do we do? Run the tests. It says expected length one to contain this but we don't have anything being passed back, right? So how do we get this? What changes do we need to make here to make this work? So we are passing the comments here, right? And in React, the way you get handled to that, what you have passed in, how do you get handled to the parameters that were passed in? So they use this dot props dot whatever name you gave there, right? Whatever name we gave here, commence. So if we said ABC over here, it would be this dot props dot ABC. So whatever properties were passed in were accessed through this. So once we've got this, we're gonna say if commands dot length equals zero, then return this guy. Else what do we do? We need to basically return for all the elements that are there in the div. We need to basically attend return but right now we know there's only one element. So we can simply just return that one element that was passed in, right? So what would that look like? So this is basically div class name. The outer thing is comments, right? We said this div dot comments is the outer thing. And inside that we expect a div and then something like class name. What did we give the class name here as? Commends header, comment header. And then comment body, sorry. The test won't consider the first div. If that first div will only be returned if the comments length equals zero. That's okay. Yeah, we'll see. This should work. This is just the outer div, right? Which we are basically unwrapping here by saying get DOM element. So we're actually removing the outer div and we're getting the contents from within that. So here what do we expect to have? So we're gonna say comments, zero. We can just hard code it for now. We will change that later. Dot user. And here we're gonna say message. Will this work? Sure enough, it worked. But this was not a clean way to do this, right? This is kind of a hacky way to do this. Again, the point was to kind of quickly get the test to work and then we can look back and improve the design of this, right? If always I only had one comment, this would work. No problem, right? But what we want to do is we want to pass multiple comments and that's what is the next test that will force us to write the logic which will get us to multiple comments, right? Also, this looks like a component in itself, right? Like we are saying this is a comments component. This could actually be a comment component, just a single comment component. So we'll start doing some of these refactorings and organizing the code much better so that this code starts looking cleaner and better. Clear so far? So what's the next test? Should we write the next test or should we refactor? We should refactor. That's what I would do, right? I want to basically take this guy and I want to refactor not that guy, just this guy. Right, I want to take this guy and I want to refactor this guy to basically be, let's say a comment component, a comment component and this comment component is going to take what all parameters. So first of all, let's store this bar. Current, or just let's call it comment equals, oops, this is our comments of zero, right? The first element, we'll refactor that little later, but now we have a comment and so we are gonna say, these guys have a requirement that you need to give a key to any component that you're putting in. The key is basically the ID of the comment that we have. So we're saying comment dot ID. And then what else do we pass? We pass the whole thing. We simply pass the whole comment object to it. Let me go ahead here, create a new react component. Let's call that comment. And that basically spits out the standard template for us. Now we can take and plonk, oops. Let's go back to our history and pull it up from there. That's the one we want. And here, now instead of this, we are gonna say what? This dot props dot value, right? Because that's what we've called it over here. You guys see this, yeah? Okay, we are passing, why are we calling that props dot value is because here we are passing, this is a value. And so this will basically be the value dot user value dot message. Let's run the test and it passes. So we did one refactoring as we are going through this where we basically pulled out something that started bloating in our existing comments component. We pulled out a smaller comment component and let the comment component now evolve as it goes along. Right, I'll quickly pause here so far. Is this making sense to you guys? Very simple bare bone example to kind of drive home the point of how we actually apply test driven development in a front end UX kind of UI kind of a work, right? What is the next test you're gonna write now? You can, but that's not test driven development. Absolutely, why not? After the fact, right? You're saying the problem sometimes might be is that your existing design might be in such a way that unit testing it might be harder because it's too tightly coupled or it might have other kinds of problems, right? So you might have to do some amount of refactoring to start with to actually make it more testable, right? So it can have things like external dependencies, for example, and external dependencies, whenever you're gonna try and run the test, it might send an SMS or something else or it might go and call, look up something, right? So that is something you want to avoid. Like make an Ajax call to the server, for example. And when you're trying to unit test, you don't want to actually go to the, you don't want to make the Ajax call. You instead want to stub it out and you basically want to simulate what the server would have given. In some sense, we are doing that, right? Because we are directly feeding in the JSON over here, right? So we've avoided for now to start with the Ajax call. Later, we will add the Ajax call and this will actually directly call the server and get it back. But to your original question, you can write test afterwards. It's just that the design might be not very conducive for unit testing. No, no, I'm using React.js as a tool for actually development. But if you're using Angular, then you would basically use Angular tests to use that with this thing. What I'm doing is there are a few things. Okay, let me step back. Maybe it's confusing. This Karma, which is the runner, okay? This is basically the one which will run these tests and it doesn't care. You can put whatever, Jasmine tests, JS unit tests, something else. You can put whatever, right? Karma, Mocha, these are all alternatives. There are different kinds of runners, okay? Then inside that we are using Jasmine. Jasmine is more of a BDD style testing framework or spec framework, right? Where we are saying describe this guy, it should, it should, that kind of a sequence. With JS unit or other kinds of unit testing framework, it would be functions, tests, something else. So they are slightly different styles to express. When you run these, right, over here, you can see in the bottom. It's, notice that says comments wizard should display this, should do this, should do this. So it gives you like a nice documentation of what's your expected spec of this component. How should this component behave? So that's basically Jasmine, okay? Then all these two contain element, two contain text, this find, these are all jQuery methods that I'm using. So I'm using Jasmine jQuery plugin, which basically allows you to poke the DOM and get elements out of the DOM and assert what's going on over there, okay? Expect is a Jasmine method, but to contain find, to contain text, these other methods come from Jasmine jQuery, okay? And here we are saying tests util, render into document, this component. Instead of doing this, this is, this is something that's very specific to react. Instead of doing this for, you know, if you're using any other framework, you would do it slightly differently. But you will get back a handle to the DOM. And then from there onwards, ideally these all should look the same. So if, let's say tomorrow we decide to switch from react to some other framework. Ideally the only line that should change is this, okay? Everything else should remain more or less the same. Clear so far? Jasmine is like, yeah, N unit, N unit is more of, so there are two kinds of frameworks. One is a unit, X unit framework, that's a unit testing framework. So N unit, J unit, JS unit, these all fall under the X unit frameworks, okay? Then you have the BDD frameworks. So Cucumber, Jasmine, Flow, Spec, a lot of these fall under the BDD style of writing specs basically. Specs is a slightly different word for tests. It's more in this format. Describe it should kind of stuff. Right, so they're slightly different kinds of framework. Okay, you could, I mean, we could write this exact same thing in JS unit, for example, or right now we are using JavaScript, but if we were writing C sharp code, you would use N unit. Or if you're writing Java code, you would use J unit. They are the runners. They allow you to run these things. So if you actually notice here, this config file tells you what is the configuration, how you want to run this. You could change these things, what browsers you want to use. All of that information is what Karma does. Karma also starts its own server and renders these files and stuff like that, right? So if you notice here, there's a Karma server running, okay? That's what Karma does. It's a runner. It's like a container in which stuff will run, okay? And what Jasmine does is Jasmine allows you to write the specs. Philosophical difference. Philosophical difference as in X unit is more of the TDD school of thought. BDD is slightly different because they focus on the spec, not so much the tests. So, you know, that's a philosophical difference saying that we are trying to write the spec of what we want. We are not necessarily writing all permutation combination of tests. It's slightly different thought processes. And BDD also is meant to be more, you know, like these things are more end user facing kind of things. So there the focus is more on creating spec that is more end user facing. If you look at these, I can show it to a non-tech person and ask the person to verify if I'm building the right thing, right? If this can get a lot more complicated, like in a bank's example, let's say I have a lot of different kinds of bank transactions that have happened. So I can put all of them in table and then I can say, okay, what's the final balance that is left? And I can capture all of this in a nice spec format. And I can use that. So that's more of the BDD school of thinking. You are writing the spec as you're writing this basically. You take acceptance criteria, you convert it into acceptance tests. Acceptance tests, acceptance tests are acceptance criteria, plus example, plus scenario, plus data, right? And that's what we're trying to capture over here. We are taking each scenario. The first scenario is no comments are there, what should happen? One comment is there, what should happen? Multiple comments are there, what should happen? Those are all different scenarios. The acceptance criteria would be around what should be displayed, right? In this specific case, we are saying there should be an empty div so I can style that differently and I can show, like I can have a nice fancy looking different div, right? When I have other kinds of things, I want to show different kinds of things. Absolutely, you should, right? And ideally I like to do that because that really helps. So if we went here, I'm just gonna, so all this has is this basic stuff. And then here we are gonna include our comments and here we're gonna include our comment. Those are the two things that we have, the components. And then right now all we have is basically message instead of author, we have user, right? And the other things are just gonna get ignored so we don't have to worry about that. Then you have the comments component and what does this guy take? It takes comments. So that's comments and we pass that in. And we are saying there is this div element in which you want to show this. So now let's basically run this guy. So notice that, oops, this is how the UI is looking. Of course we didn't put any CSS, right? So if we went in and added some CSS, we can start styling this. Jim Shore was here, I don't know if you guys saw Jim Shore's keynote, but he also has built a tool for doing CSS unit testing. For testing CSS and there's some pretty interesting things. So right now we are not actually unit testing our CSS, but let's say we even wanted to unit test our CSS, Jim Shore has actually built a tool for doing that. We are only showing one right now, if you remember. I mean there's no code, how will it show? We've not written any code here, right? We just hard coded right now to pick the first comment always, right? So we need to go and fix this where we're gonna write a test where we're gonna pass multiple comments and we're gonna show multiple comments in this, right? Let's actually fix our CSS real quick to make sure this works. So the problem is that all of these guys are, I think that should do the trick. Let's directly open this. Where is this file? We have to figure that out of where we are. Okay, this needs to be rendered from the server, that's why it's not gonna work. Yeah, I'm trying to figure out why the CSS is not working. Ah, there we go. Notice that CSS now kicked in and it's kind of giving some styling to our comments. If you guys want to continue, I can show a few more examples. If you have more questions and you'd rather do a Q and A kind of a thing, we could do that. The other thing I can also do is I have this example ready and I can kind of jump in and show you what the end code would look like once we've actually built the whole thing as we go along this fashion, right? So the next spec that we would write, obviously, is multiple comments and so that we can get rid of this hard coding that we have done here. Different companies do it differently. So I don't know if there's one answer, but ideally the way I do it is basically we do something called as the product discovery where we do the product discovery with the whole team. It's a collaborative product discovery where we actually do UI prototypes, low fidelity prototypes and all of that stuff to figure out what are we trying to build and then we take that, start slicing it into vertical end to end slicing business functionality and then developers would sit with the subject matter expert and write the spec down and then they would go off and start writing more detailed code around this, right? This is a very specific example, but you would do this at a much higher level, right? And then your developers would continue doing that while the testers might write most scenarios around these. And so that way everything's kind of happening in parallel. So when the developer says I'm done, not only all the spec should be passing that they started with, but also in the meantime, the tester might have written a bunch of spec. You wanna make sure all of those specs are also passing together. But you have a general idea because you've done like a product discovery together on that feature. So that's one way in which we've used this a lot at companies. React.js is a framework like, it's an alternative framework, right? To Angular to other kinds of things. No, no, there is UI, right? It's actually bringing up the browser. It's actually running here. And it's also starting a server and doing it, right? So again, I guess I kind of jumped ahead and React is a framework by Facebook for building web UIs and also mobile UI. You can do both, right? And this uses functional style of programming. So in this nowhere, I'm mutating state. All transformations are happening by the framework. I don't actually mutate, unlike jQuery. In jQuery, you go and manipulate the DOM, right? Here, I'm not manipulating the DOM. Did you see me writing any, manipulating any DOM, finding element, putting that element inside it? I'm just creating what I want and then giving it to React. React will take it, it will apply a div. It'll apply a div on the virtual DOM and it'll basically render only the elements that are slightly changed. Only those portions will get rendered and all of that stuff is handed as transformations, right, the functional style of programming. So there, you're not mutating any state or any of that stuff and it just becomes so much more easier to think about your UI now. There are lots of different paths that are changing. All you're saying is, okay, this got updated, this got updated, this got updated and it takes care of how it needs to render it from a performance point of view and also from multiple simultaneous changes going on. Yeah, we are doing a data binding, but it allows only one way data binding and that's by design because you don't want a lot of back and forth. The two way data binding is something that confuses the heck out of people. Angular suffers because of that in my opinion. Angular or a bunch of other frameworks. Sure, I mean input from the UIs, you have form elements, you have buttons, you have other kinds of things. So I'll show you what, let me jump to the other example. No, no, no, no, no, not necessary. When you refer to two way binding, it's slightly different. So here's the actual full blown example. We'll look at what this looks like. So you can do before each stuff like that. Should give a nice message, this you have seen. The second one you have seen as well. This is the third one, should display the most recent comments on the top. Right, so this is my data. I'm giving it to render this data. And I'm also saying who's the logged in user. Then I'm basically checking the length should be same as the length of the data. And I'm checking that the one of these is Jack, one of these is James. So I know which is showing in which order. Should not display private comments, yada, yada. So here basically we are saying JSON.private is true. So when you go here, even though the comment exists, it basically shows be the first one to add the comment. I mean, there are more stuff in terms of how we do. So here we are stubbing out the JSON. So we are saying Jasmine, Ajax, stub request to this URL and return this back. It automatically will do a binding. So anytime this URL is requested on Karma, Karma will intercept it and just give you this data back, right? And now I can say source URL. So now I'm not giving the comments, but I'm actually giving the source URL here. And if it takes the source URL, then it again expected same Jack and James in this order. What happens if it results in a 400 bad requests, right? What should it happen? It should show like fail to fetch comments from the URL, some message, stuff like this. The beauty of this is as we actually designed this, you'll notice that models have emerged and views have emerged. So if you look at, and this now starts getting more complicated into react specific stuff. There's a get initial state. There's a set state component did mount. So react has a life cycle. And finally the render method is called. We are saying if Ajax.error state, then basically show this message. Then we are saying get all the authorized comments. We got the comments. If it's empty, then display this guy. Else do the standard thing that we were doing. And here basically we are saying comments.map and call this method, which will basically create your comment component. Right now we had done a single one if you remember, right? The easiest way to change that is to say comments.map and give it something, which will basically call the function. This is the power of functional programming right here. What this does, it basically calls this function on every element of the array that we are giving to it. Right? To do this in object oriented, you'd have to write 10 lines of code at the minimum. Don't judge the book by looking at its cover, right? Yeah, so what I'm trying to get here is basically this is more of a functional style of writing this, right? And the life cycle, there are reasons for the life cycle in React. And in my opinion, they are a lot more meaningful and a lot easier for program to understand than other, this thing. So again, I'm not here to sell React. That's just the tool I'm using to demonstrate how you can do test driven development in web UI. The same thing can be done in Angular or whatever tools, whatever frameworks you guys use. The point I was trying to make here is that I can simply take an array call map and pass a function to it, which will basically render my components, each of the components. So what it is doing is it's taking each of the comments from this array and rendering a comment component for it. And the way to actually, so here you will notice when you update likes. So to your question, the two way binding, the way the two way binding here works is I pass a function, a callback function, and I'm passing a callback function to this component. So when someone clicks the like button, so I have a form element here and let's say I have a button. So if someone clicks this button, what is gonna happen now is it's basically gonna call the callback function, which is basically the props.update likes and it's gonna pass the ID of which comment you actually clicked on. And that in turn will basically update the refresh the whole UI because if one of the likes increased, it needs to go above the rest of that, right? So it allows all these re-rendering, if it was some other framework, we have to do all these re-rendering, right? Here you're just saying, hey, react this change, this is an update, the state got updated, it'll automatically apply the diff and move just whatever comments needs to go on the top, just goes, gets moved on the top. So I think it's kind of quite powerful from that point of view. And there's like very little code in my opinion that we need to write to make this work. Which one? So yeah, there are a couple of things from React. So this Lava brackets, you can see, the Lava brackets is the React syntax to basically put JavaScript code inside. And then it also has JSX, which is you can write actual HTML inside JavaScript. It's not binding data here, it's basically whenever you put curly braces, you can write JavaScript within it. Because you're writing JSX, which is HTML, right? And if I want to do like PHP, it's templating. It's basically templating if you, so you put curly braces and you put whatever JavaScript you want to put in there. It's not binding, no. Not like handlebars or stuff like that. So you also saw how we were doing, we were stubbing out Ajax requests here, right? So I showed you the example where I'm essentially creating the expected JSON response. I am stubbing out the response and then I'm calling the render component with the URL and this would basically get stubbed out and these three things would get returned over here. And that's what I'm verifying in this case. That the Ajax response length is the same and this thing. This I find extremely powerful as a way to basically stub out the UI from the backend and be able to test it nicely, both the error conditions, the happy path conditions and so forth. When you have two way bindings, this is a lot more difficult from my experience, but it can be done. There are tools and frameworks to do this. It's just a little bit more complicated here. It's as trivial as calling the URL and stubbing it out. We talked about the models have emerged and the components have emerged. We quickly wanna just touch upon that and then we can open the floor for questions. So right now this is what my comments component looks like. This is what my comment component look like. We were looking at the form and the submit and things like that. So you can do stuff like that. And then if you look at the model that we have emerged. So we've essentially taken the whole logic out of the views and you've put it in the model and you can essentially run a stuff. So this is kind of where I was talking about the marriage between OO and functional. So this is like the models are OO, but everything else, the rendering and all is functional. So it's kind of the nice balance between the two that you can achieve. React itself does not tell anything. This is just how I ended up test driving it. I ended up pulling out these things into this so that I can actually write a spec around these guys and actually test all my model and my logic because I have a bunch of logic that's going on over here. I don't even need to render these things to test out the logic. So the point I was trying to demonstrate here is I would actually pull out these models and unit test the models without actually having to even bring up the UI. And so once you have these functions, now you can simply write a spec around these and you can easily unit test your models. I thought I had the test, but it doesn't look like I have the test here. I can show you in another project, a more real project maybe. This is basically, you would write a similar spec, right? So in this spec, what we are saying is render component. Instead of saying render component, you'll basically say new comments, right? And this comments, where is the comments? From the spec, you will directly call the model. You'll say new of the model. And then let's say you will call compare to and you will pass another model. And then you will assert whether you got true or false, right? So you can now, correct, you create an object of this and then you just test. So your model, because it's an object, you can just instantiate from the tests and test that in isolation. So you can nicely now unit test your models. That's again, what I'm trying to show here is that in JavaScript, a lot of times what people end up doing is plunking everything together, right? The model, the view, the logic, everything is all plunked together. And if you start separating the concerns out, right? You'd be able to easily unit tests the models. You'd be able to test your UI, but that is more than unit testing because you're actually doing a browser round trip, right? But you'd be able to test these things out in isolation. So any logic that I have, the logic should be able to unit test easily because now I've pulled these logics out of this, right? Whether I can give a list of comments and I can say give me authorized comments back. So this guy's gonna filter out the unauthorized comments and only give me the comments that I'm allowed to view. I don't need to do that on the UI. I can unit test that without the UI, right? And so that's very powerful again. That's JavaScript. There's just a way to add more functions to the prototype as the base class. Basically, you would say, you know, depends on two strategies of structuring this, right? One is basically functionally, you start putting things together. So each functionality part, the view, the model, everything is inside one top-level folder. The other way is to basically have all the models in one place, right? And maybe subfolders within those models and where to logically group that. I don't know if there are any standard conventions. People use one of these two. Whatever we've done, nobody, none of this would matter because all you have to do is in your config file, you have to specify where to find these classes. Doesn't matter. All you have to do is you have to basically say where to find them. So here I'm just saying source, start, start, start.js, right? So it doesn't matter how many nesting you have, how many levels of nesting you have. It'll just pull out all the JavaScript, load all of the JavaScript. So if you see here, we are doing that, right? Basically, what you can do is through jQuery, you will basically get a handle to the button and you can simulate a click in React test itself. There's also a way. So if you give an ID, a key to your React to the button, then you would be able to basically simulate a click event on the button and then you would be able to test what happens if you're doing that. So either through jQuery or through React itself, you should be able to simulate a click from the code. All you need is the key or the ID and you say, okay, this dot click. Like you would write it typically in JavaScript, right? To click something. So same way you can simulate it from here and see once you click what happens. The challenge you might run into is if it's asynchronous that it basically when you click, let's say it goes to the server and then refreshes something. So that time you'll have to basically again stub out the call and make it more or less synchronous. Okay. Inheritance is the worst thing that could happen to object orientation. So that's the worst thing that a large regions, a large reason of programming problems are because of inheritance if you actually look at it. There's someone goes and adds something to the base class. Now all the child classes have to basically adhere to that, right? Otherwise you end up with violating the list of substitution principle. The other problem is this is referred to as a white box reuse. Inheritance is referred to as a white box reuse instead of a black box reuse, which is composition. And whenever you use a white box reuse, you are more tightly coupled. And when you're more tightly coupled, the chances of someone changing something and having unexpected behavior somewhere else is very high. So we might not go into the oh versus this. Originally I was saying the reason to start moving functional is, and I was the way I was kind of trying to demonstrate that is all the UI related stuff. Now basically the changes is happening in a very functional way because you just recording your changes, tuck, tuck, tuck, tuck, tuck, tuck. And then it just does a dip on the virtual DOM and applies that, right? So that's a very functional way of thinking of manipulating stuff. And that works really well in the web and the mobile paradigm. And a lot of companies are moving in that direction. And here I was demonstrating a nice balance between the two where some models and this, but you could completely do away without the models, right? You could simply have a bunch of functions. You don't need the classes, but so you're questioning the whole premise of TDD. So two things, right? When a change comes in, the first thing ideally you would want to do is actually update the tests to say what should be your new expected behavior now. They're all, yeah. So this is like the comments component, right? I might have some other components. So each component would have a, you know, spec with it, right? So if let's say comments some logic change, we decided that instead of likes, we're gonna do some other way of sorting it, right? Then I know where to go and look for it. So it should not be that difficult to maintain. Having said that, if people write tests really badly, then maintenance becomes a huge nightmare. Like the, some of the tests I'm showing can start getting a little bit complicated. Once you have too many elements on the screen and you're trying to change too many, but again, the advantage of React or frameworks like that is component based frameworks is you only now dealing with the component. These components now can be plugged on a single page. However you want it, but you've individually just tested your components, right? So that gives you a lot of flexibility to move things around and adapt as things evolve. Sorry. I mean, there are enough projects. Actually in our code base, we don't have models. We just group them all as functions. So we don't have, but I didn't want to give a big shock over here. So I put in models. People feel a little comfortable. Okay, this is cool. But I don't see the absolute necessity for models here, right? You can easily do without the models. So that's exactly what React is trying to address is basically state management is a really complicated this thing. So instead of you having to maintain the state and manage the state, you ask React to do it on your behalf. And so in React components, you will see they have something called as a state. So like comments is essentially a state now. And so anytime comments changes, it will automatically call the render function for you. That's all you need to do is update the comment and let's say the number of likes increased, right? So if I update the counter of number of likes, it'll automatically re-render the UI and only the diff elements will get re-rendered. That's the power of this. And so you don't actually have to maintain the state and do the state transformations and all of that. So that gets handled by the framework for you. So that's the power. Again, this is not a tutorial on React. So we won't be able to go into too much details, but something that you might want to go back and refer. It has a lot of promise in my opinion. Cool, we have last 10 minutes left. Any other questions people have that we didn't address? Court coverage tools, there are a whole bunch of court coverage tools, JS lint and other kinds of things, JS cover which basically gives, I think you're gonna touch upon them, next, all right. So hang in, that's a plug for the stock next. He's gonna do a demo on all the CI related stuff. So I've not gone into details of that. I'm sure he's gonna cover some of these elements. What are you using for? Are you using R? Are you using, okay? All of them have wonderful unit testing frameworks out there. So you don't need to reinvent the wheel. It's all there. I unit, I unit is pretty powerful. It lets you do a whole bunch of stuff. Scala has again framework, R has our unit. I think that's what people use. If you're using, if you're not using R, then SAS is the other tool, a lot of people use for analytics. I used it and SAS, we have something called a SAS unit. So you can do quite powerful unit tests of your models and stuff like that. I have a slide, I can quickly bring that up, which is my view of how testing should be done. If you don't have any other questions, I'll bring that up and we can spend some time looking at that because that's a fairly detailed. So this we talk about the typical ice cream cone problem in the software testing field where there's a huge number of end to end tests that are there, very little unit tests. And then a massive amount of manual checking that is done to basically certify anything. And this is basically the lousiest way to manage software projects, right? This is this, any time you wanna make a release, this becomes a huge bottleneck for you to get something out of the door. So we talk about flipping that to a model like this. So there are many different layers of tests and these different layers of tests, each kind of addresses one problem, but again, the pyramid is important in terms of the amount of end to end tests versus the amount of unit tests and business logic acceptance tests is, you know, you can see from the pyramid, like very little in the top and a very heavy focus on the bottom, right? So each of these, so unit testing, again, depending on the technologies that are at play, you can have many different tools, right? Because for example, in this case, he's looking at R as one of the things. So now R might need to be tested and some of the workflow tests will actually cut across all of these things, but these are more at the API level or stuff like that. You would go one level up and you'll actually slice out like what we were doing the UI part and actually do a one level below that. And finally, you can write a whole bunch of unit tests at the UI itself, like the model test and other kinds of tests that we were talking about at the UI itself and the look and feel based tests. Just like mapping pixel to pixel, some cases that's very important, especially for reports and stuff like that. And for those cases, you might actually write a few UI tests, GUI tests. GUI is basically the actual pixel position of something. You want it, you want to verify those kinds of things. You also want to verify the navigation of things flowing from one page to another page from the UI. So things like that is what would fit into the GUI test. But there'll be very few, right? You will take five or six use cases and have simple ones because vast majority of it is actually pushed down and tested, right? You don't need to do all of that on the top. Two completely different things. Selenium is what would fit there, your GUI, right? This is gonna fit here and here, Jasmine. So Jasmine could be used for unit testing as well, all right? Jasmine could be used for this. Jasmine could be used for integration test. Jasmine could be used for workflow test. You would use Selenium or something else for the GUI tests, right? End-to-end test, one layer below would use part of Selenium as a driver. Actually, you probably won't even need Selenium there. Only Selenium would fit into the GUI level. Everything else below this, you could use something like what we were doing now. We'll take it offline, which I just wanna make sure we've wrapped this up, this kind of slightly off topic, but we can take this what it means. It's a 20-minute discussion, not a one-line discussion. All right, I think we're almost done. If there are no other questions, then we'll wrap it up. Cool? Okay, thank you. Thank you.