Part 1 — You’re here now. . Part 2 — Link . Part 3 — Link . Part 4 — Link This tutorial assumes some knowledge of JavaScript, the front end, test-driven-devlopment and the node package manager, with little-to-no experience of React / Redux . It’s my opinion on how it should be done at this very basic level while you’re still learning, and it should at the very least open avenues for you to pursue your own best practice. The less you know about React the more I recommend you branch off and read supporting links. High production value Introduction The above beauty is what we’re going to be making in this tutorial — a React Todo list app, using Redux as our state management system, TDD’d with end-to-end tests using and unit tests using . webdriverIO enzyme You can view the finished app . And the final . online here on heroku git repository here We’re going to be using the node package from Facebook to scaffold the essentials of our app. If you’re completely new to React then I’d recommend a couple of times to get familiar with all the packages and configs, but for the purposes of this tutorial we’re going to skip ahead and let create-react-app take care of that for us. create-react-app setting up an app from scratch Even for a production app, my feeling at the moment is that it’s better to use create-react-app and then make the few changes you may want, it’s far more efficient. You can have a look at what create-react-app actually does behind the scenes in this repo , all I’ve done is scaffolded an app and then run _npm eject_ to expose all the packages, configs and scripts. Files of note will be the _package.json_ and contents of the _config/_ and _scripts/_ folder. Creating the app Make sure you have the latest installed. node and npm Then install the create-react-app package globally: npm install -g create-react-app In the command line let’s go to the parent directory of where we want to create our app then run the following: create-react-app my-react-todolist This will create a react app in the folder relative to wherever we are. my-react-todolist/ Then let’s change in to that directory and install the node packages we need: cd my-react-todolistnpm install If you have a look in the you will notice that the only production dependencies are the library and to render it, and the only dev dependency is something called . Herein lies part of the magic, it’s simply a package that has all the most essential packages as its dependents and provides scripts to run common tasks. You can view more on the . package.json react react-dom react-scripts npm page here Let’s run the tests as a sanity check to make sure everything has gone according to plan. npm run test You should have 1 passing test. Let’s run our app and see what it does. should start the server and open a browser window at npm run start http://localhost:3000/ We’ve done it! We’re React devs. Time to get paid. At this point I would probably make my first commit and push up to git, but that’s your call. Git commit State of the repository Eslint This bit is optional, and if it’s your first time using a real-time linter then you’re going to find it to be a nuisance to begin with, but it’s an essential tool and you may as well get used to it if you aren’t already. Linting is very useful for a number of reasons such as; enforcing style rules and best practice, removing unneeded code and decreasing cognitive load. My current favourite is with the rules, it’s not very hipster but it is the most popular and probably the most relevant choice at the moment. eslint airbnb npm install --save-dev eslintnode_modules/.bin/eslint —-init These are the options I used and would recommend you use: We’re going to add an exception to the rules at this point, we’re going to tell eslint not to complain when we write JSX in a file. .js The overly-simplified definition of JSX (JavaScript with XML) is that it allows us to write far more concise and easily readable React code, including standard html, in our JavaScript, read more . "rules": {"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]}, Your eslint might look slightly different depending on the version but this is what my config looks like: .eslintrc.js Git commit State of the repository Refactor Let’s do a little spring cleaning with our app before we proceed. We can make good use of our new found eslint-powers. Open up the and we should see eslint complain about the App component. It wants us to write it as a stateless pure function as opposed to the stateful React component it is now. src/App.js // A stateful React component class App extends Component {render() {return (<div>My App</div>);}} export default App A full-on React component gives you access to all the and the ability to store and mutate the state but it’s not really the nicest way to write our code if we can avoid it. lifecycle methods Pure functions have the bonus of being really nice to test, they always have predictable returns, are more performant and are written in an immutable functional style. // A stateless pure function const App = () => (<div>My App</div>) export default App Pure functional patterns were added in React 0.14 in 2015 and I encourage you to embrace them, they are a lot of fun to use. But… you should also know how to write stateful React components for when you need lifecycle methods or to mutate state in the component itself as opposed to in the state management system (Redux in our case). Read about and read more about the differences and . stateless pure components here why you should use them here This is how I’ve refactored my , removing all the boilerplate in preparation for creating our Todo list: App.js Let’s refactor our one and only unit test to use , a utility that makes it easier for us to test. We’ll also need to install the react-test-renderer dependency. enzyme npm install --save-dev enzyme This is what my looks like now: src/App.test.js We import the module from the testing library. This will make it easier to . More info on rendering methods, selectors and assertions can be found in the . Line 2 shallow enzyme test in isolation enzyme docs If you’ve not experienced ES6 _import_ syntax before then MDN has some good documentation you should skim. It’s a nicer way to _require_ files and sub-modules but it does require transpiling. Then refactor our tests to shallow mount the component and assert that it exists. Line 6 — 7 Eslint might complain that and are not defined. To quash those errors we’ll add an exclusion at the top of the test file. it expect /* global it, expect */ Make sure your test is still passing and that your App still loads in the browser, just with very little in it. Git commit State of the repository End-to-end testing Before we get carried away and start coding let’s write an end-to-end (e2e) test that actually tests that our app performs as we want in the browser. You may call it a feature test, or an acceptance test, or UI test. Our e2e testing solution is going to involve letting us fire up a browser, controlling it and granting us assertions. [selenium](https://www.npmjs.com/package/selenium-standalone) [webdriverIO](http://webdriver.io/) [chai](http://chaijs.com/) npm install --save-dev selenium-standalone webdriverio chai And perform the setup for webdriverIO: node_modules/.bin/wdio config These are the settings I used and would recommend: Make sure you have installed and then edit the to select it as our default browser. Search for: Chrome wdio.conf.js browserName: ‘firefox’, And replace it with: browserName: ‘chrome’, Before we can start our selenium server we have to perform a one-time setup. We could do this manually but if we want to make this repo easily useable by anyone then we should really set up a task. Later we will document how we setup, start and test our project in our readme. In the let’s create a few scripts to handle our e2e testing needs: package.json "scripts": {"selenium-setup": "selenium-standalone install","selenium-start": "selenium-standalone start","e2e-tests": "wdio wdio.conf.js","e2e-tests-watch": "wdio wdio.conf.js --watch",...} Here’s what my looks like now: package.json And then setup and start the selenium server: npm run selenium-setupnpm run selenium-start Super! Now we can actually write our first e2e test. I manually entered the folder in my wdio config so I’m going to write it in there. If you went with the defaults then your tests should go in the corresponding folder. e2etests/ To get more acquainted with how to use webdriverIO head over to its . API docs Now if we run we should get a failing feature test because we haven’t changed the title of the page yet: npm run e2e-tests We can run _npm run e2e-tests-watch_ if we want to run our e2e tests in ‘watch’ mode, this just means webdriverIO will watch for changes in the files we’ve told it to track via the _wdio.conf.js_ and then rerun tests upon a save. This is more convenient but may sometimes give us unwarranted failures, just beware of that while developing. Head over to the and change the: public/index.html <title>React App</title> to: <title>Todo List</title> And behold the green glory of a passing test. Git commit State of the repository Recap We’ve learned how to: Set up our development environment. Create our React app. Use Eslint. Refactor to ES6 syntax. Set up e2e testing. Get our first e2e test to pass. Up next Now that we’ve set up most of our app and gotten a bit more comfortable with our workflow let’s move on to writing unit tests and adding our first todo. Part 1 — You’re here now. . Part 2 — Link . Part 3 — Link . Part 4 — Link
Share Your Thoughts