 Before we start, is somebody here not familiar with GraphQL? Oh, that's like half of you, okay? I will tell maybe a little bit about GraphQL. So GraphQL is a query language for your data collections. It's a little bit different from collecting data from REST APIs. REST APIs usually have a single endpoint with fixed data structures. If you want to get a collection of your products or your users, you're going to access one REST API endpoint. And in the case of GraphQL, you can combine all those collections into one single endpoint that has flexible data structures. So we're going to look at some GraphQL queries later for the people that aren't familiar with this. Throughout these slides, I will use an example with React. People are using here React or... Okay, that's better. Okay, so I will use React in most of the code examples. So it's always an important thing to add testing to your code, especially when you have a JavaScript application without the dynamic type system, not like something like TypeScript. Then it's really important to have testing scheduled into your development process. So this is a meme about a guy from Futurama that's wondering if his code is working or just his tests are broken. Like the people in here that are using... that are having like a test coverage levels inside of the deployment phase will probably know. You need to have a working test and test above a certain coverage to make sure your code is working or just your tests are really wrong. So who am I? My name is Roy. I'm from Amsterdam. I work with JavaScript a lot, both professionally at the city of Amsterdam but also at conferences and meet-ups or workshops I host about React. You can find me on Twitter as well. It's at GetHackTeam and then I tweet a lot about JavaScript or React, React Native and GraphQL as well. This presentation is about for everyone that's using React applications, JavaScript applications, or maybe GraphQL. I will show both how to test JavaScript applications, reduce GraphQL and GraphQL queries and mutations out of the box. So if we have a small look at this testing pyramid, this is like the traditional testing pyramid with the unit tests. On the bottom, the integration tests in the middle and end-to-end tests in the end. And this also, like in level of complexity, unit tests are fairly easy to create. Integrations tests are a bit harder because you're not testing single components or individual pieces of code, but how code connects with each other. And end-to-end test is usually the most difficult one as you would usually mock a browser or use something like Cypress to do it and really see how user will interact with your application from page to page. And so this will focus mostly on unit tests because it's a bit hard to explain integration and end-to-end tests in one single presentation. Before we have some criticals, there's a new approach for testing is usually something like this. It's like an upside-down diamond or what is it, a five-point polygon. And as you can see, unit tests are on the bottom. Integration tests are in the middle. End-to-end tests are on top. Making end-to-end tests and integration tests much more important. But like I said, we will focus on unit tests for now. And maybe if we have time for questions, we can discuss how to do integration tests as well. So why should you write tests? Like I said before, tests are important to see if your code is stable and usually it's an indication if your code is working as well. So you will test if your code will work as expected. So usually when you have a project with a good test inside, you can see all the functions from the project by just looking at the descriptions of the tests. And you will also see if you can handle errors and edge cases correctly. And this is also something I will show in an example. And you will also test if your syntax is handled correctly, especially with JavaScript. As we have a dynamic type system, unless you use TypeScript or maybe Flow if you're using React, you're not always sure if a variable you're passing always is an integer or a float or a boolean. It could be the case that your integer is instead of float or you're expecting a string and sending an object. So usually if you have unit tests in place, you will notice when you're testing that your code isn't working as predicted because one of your variables has a different syntax. For testing JavaScript, there are a lot of frameworks or applications that are available already. I will mention some and maybe some people will recognize them. At first we have Mocha, which is a JavaScript test framework. People use it a lot when they are running Node.js applications or want to test something right in the browser. We also have Enzyme, which is a JavaScript testing utility, usually for React, and it simulates the React DOM and React components. And this is a much more advanced version of the code I will be using. I will be using the React test details for examples and Enzyme is a more advanced version of that one. You also have Chai, which is in the search and library, so if you expect stuff to be equal to each other or not equal or you want to know if one of your actions has been called or an API has been called, then you can use Chai assumptions for that. And in the end we have Jest, which is sort of into the box with React and it was created by Facebook and the examples I will show are using Jest. We also have stuff like I mentioned before, like Cypress. Cypress runs on the browser and it mocks the browser behavior with Puppeteer and then you can see how people click to the application. That is far beyond the unit testing we will discuss today, but it might be good to know if you want to integrate testing in your project. So we are going to look at an example that uses GraphQL and I am going to show the schema first. So we have a schema with a product, a review and an offer and as you can see the review and offer our dependence of product and for people that are not familiar with GraphQL this schema has the basis of your application and we are going to define each type like we would define our database scheme, in example. So all our variables will have this format all our IDs will always be integers our titles will always be strings and so forth and the review and offer types are also described and linked to the product type. So throughout the entire application we will have a real clear ID and what structured data will be so we don't really have to test anymore if our terminal really is a string or it actually could be like an object. And the right you see two other types I have defined in the schema, one is query. We are going to query two things like the products all together and a product separately and we also have a mutation where we will add an offer to a product. If we do, for example, like an Amazon sort of application where we have products and products are offered by multiple people. So I'm going to see if I can switch it up. Yes, so here we will have the code for our project. Yeah, so the application we're going to test is this one. So we have an offer, we have a product in this case a blue t-shirt and it's offered by three companies and we can add offers to this one. So if we want to add a reseller with a price we can add it like this and we see the new reseller is added with a price and this all works through our GraphQL schema that we have described here. So this is the entry point of our application and the page you just saw was the products page showing an overview of the products we have and below you can see there's a form component right here that let us add the offer to the product and the form component is right here. Yes, so like I said before, we have a query where we get all the products so the overview we just saw of all the products with the forms. We could retrieve it by querying all the products and the mutation, so adding another offer to the form was done by this GraphQL mutation. If we want to test this component then there are multiple options. Like I said before, you have the integration test, the unit test or the end-to-end test and we're going to see how the end-to-end test will work. Testing GraphQL is a little bit different than just testing React components. So as you can see, if we just want to test the product component, then we would have done something like this. We use the React test renderer to see if the component renders. However, this will give you an error as we are missing the whole GraphQL setup. So somehow we have to include the GraphQL setup as you can see here. Yes, the Winner Index file with Apollo provider and Apollo lets you add GraphQL to your project and we have Apollo client setup, which is our GraphQL server and we also wrapped our products component inside this Apollo provider with Apollo client attached to it. So when we're testing the products component we will also need to include that GraphQL Apollo provider component otherwise our test will fail, obviously. So that is something we can also mock it entirely. So I have a small example where you can see that we're adding our Apollo client in our test file as well, although this isn't really maintainable and also because we're directly including Apollo client inside our test files, we will also test against real-life data. So if a server is not running or you don't have a network connection, then your test will automatically fail because you can't check your schemas and your queries against the real data from the server. So this is something we also can't test with this behavior. So that's why Apollo has created the mock provider. It's especially for React components and it lets you add your schema and your mock queries and mutations directly to the components so you can use them. And this way you can test against mock data. As you can see, we insert the mock data to see if our project is working fine. And you can see our products component is wrapped inside the mock provider, which is basically the mock version of the Apollo provider we saw before. And that way we will test against the mock data. So if you have your GraphQL query and you want to return the products then we don't need the real data but you can just insert data in the mocks and it will also have the same JSON format as your real data but then with mock values. Another thing we can do is test schemas but I will show you the mock files for the components first. Yes, so at first we can test our query against the component. As you can see this is our actual component file and we have our GraphQL query defined here and we're going to query all the products with the variables and also their related collections which are reviews and offers. And as you can see we do nothing more than just mapping out the data. We get back from GraphQL and we get this data back from this query component from Apollo and we will just map it out here and as you can see we have the title and the offers and the offers all have their own variables and we also have the form component. If you look at the testing for the products component you can see instantly from how we described or test what the component should do. So the component should render without an error. That's something we can test really easy. We don't need to add any mock data because we don't need the mock data at first because the component doesn't need any data to render. And as you can see we wrapped it inside the test renderer from React. We have a mock provider and our products component and this test should work. We also have a test where we would test the loading state. We're going to see if our component actually shows a loading indicator or a loading text when we're retrieving data from GraphQL. For this we still don't need to mock any data because this is just testing the connection with the provider. And for the third one we need to actually insert any mocks. So as you can see we mock the entire GraphQL request by adding the query and the query is the same one we use in the actual component and we just import it and we're going to check if the result data matches our schema and matches our query. Something that we have defined on the front end. And this is a test that also should work and we're going to test it by seeing if there actually is a product that has the name Test that matches with the name Test in our result. And last but not least we can also test for error message. As you can see from the running example we just test it here and see if our tests are working. As you can see all the tests from the products component passed. And we also test the form component which is basically tested on the same way as we tested our products component. As you can see we have described the mutation in the form and as you can see it's a mutation with variables that we sent to our GraphQL server and which returns data if we edit our product successfully. And as you can see use the form submit that uses the React to create a rev future which we can also test by mocking those revs. As you can see I mocked those revs right here inside the testing of our form component and we do it basically the same way so we wrapped our form component inside the mock provider component from Apollo to test if it's working. We do the same for the loading state we're going to see if our component shows a loading indicator sending the mutation to the GraphQL server and last but not least we're going to check if we get a success message after our product or offer is added to the product. And this is how you can test components and if it all went too fast it's on GitHub as well I will show you a link later. Something else we can do with GraphQL is testing our schemas directly so if you're familiar with Redux for example you can test Redux Action Creators directly and see if they mutate your reducer correctly. And schemas we can test with a small open source framework package that is called Easy GraphQL Tester and with Easy GraphQL Tester we can directly test our GraphQL queries and mutations against the GraphQL server. As you can see it's a small example of how we should do that so you're just going to import the Easy GraphQL Tester and you can test your schema so you either have to need to have your schema on the front end to test on the front end or use Easy GraphQL Tester directly on your GraphQL server and you're just going to input the schema in there and then you can test if your query will work. So in this last exception and you can test directly to the schema so this will mean you get the real situation because in this case I'm importing the schema from my backend so I will always need to have the server live and you can also test with invalid values so in this case we're going to test if our mutation should return a success message or an error message so for example if I would insert a wrongfully variable I would insert and float my integer then I should have to know that my test case should fail because the format of the variable isn't the correct one and you can do the same for mutation to test if it returns you can also use mock schema so instead of your real schemas you can mock them to see if the queries you have defined are really working and you can test both stuff so in this case we will test if our products yeah, if our products query will return products in the form of an array and we're going to test that to be true so if you're interested to see more about this project you can find it on my github here and you will need the actual Apollo GraphQL server running but the link to that one is also in the index file I believe so you can test, go and start the GraphQL and start testing it in your browser yeah so if we look at the code example again then you can see I've added the schema testing I've added the schema testing into a different directory because we're not really testing the component we're just going to test if our queries work so in the component file so this is the form component and we're going to test if our actual component will render with the mock data and inside the other file I'm going to test the schemas so that's inside this file at first I retrieved the schema from my GraphQL server which is hosted on code sandbox so if you would find the project in github go to this link you will find the actual Apollo GraphQL server I'm using so I'm importing the schema and I'm testing against the real life data in this file where I'm importing the schema right here I import my queries from the components and I'm testing against the real data to see if it works so my third test will see if my query matches everything that I have to find the schema which is basically the core of the GraphQL if your queries don't match the schema you won't get any results so that's something we need to test at first secondly I will return if the corrected data is in the right format so the product should be in an array and we can test if it really should be an array by having these CHI assumptions we want to know if the result actually is a result we are expecting and in the last one I'm testing the actual mutation I describe your test mutations in the form component at first I'm going to test if my mutation would actually return me the offer I just inserted I'm going to see if that violation is true we import our mutation and we test it and we're going to see if it returns this data and that's the case we just saw the test works and in the final version I'm going to see if our mutation would fail if we insert something other for productivity so you can see we've defined productivity it's defined in our schema as a as an integer and we've defined it here as a stream so this should fail obviously yes so again you can find more information on this GitHub repository to actually have this product running and if you want to know more about this you can also go to Twitter and just ask me a question if you would like so thank you very much for your time thank you so if you have a question raise your hand I mean you have a question who is the first who is going to ask it just want to look at me looking strange maybe they understood everything no? no questions well if you're a little bit shy maybe you'll be outside of the room yeah I will be outside the room and you can just go to Twitter right there in the bottom and you can send me a message or just send me a tweet thank you