 Привет, ребята. Хорошего видеть вас. Надеюсь, что все были хорошими. Я здесь, чтобы поговорить про тестовый фронт и часть нашей вебапликации. Когда мы разработаем вебапликацию, это не достаточно для того, чтобы просто тестить наши виды и тестить, что мы напоминаем правильные хтмл, дать правильные квирисы и эти квирисные информации для браузера, для того, чтобы consumить хттп. Иногда в вебапликеции браузер-интеракционная часть является очень комплексной. И в этих днях все пытаются построить синглпейсовую вебапликуцию, где вы не должны расширить пейс, вы просто делаете информацию назад и назад, и вы идете в фейсбук пейс, вы идете в гиммейл пейс, и вы expects everything to be smooth and working. И для теста мы должны делать синглпейс, мы должны делать все тесты с одной стороны и с другой стороны, как это выглядит. Самый популярный пейс для теста с синглпейсом, я буду объяснить, как работать с ним и покинуть какие-то лучшие практики, которые мы используем, когда мы работаем с синглпейсами с синглпейсом. Инстализация с синглпейсом не usual people install selenium, but the second part is a bit extra is that selenium automates real browsers and it needs a bit of intermediary layer between a real browser and this library. It communicates with a browser where HTTP and JSON protocol called web driver protocol. It is actually now a W3C specification which is going to be adopted soon. It is currently a candidate release and Mozilla and Google are working to implement it in their browsers. They have already actually implemented it. Those web driver drivers which you have to install are released by Mozilla and Google themselves. They keep them in sync with their releases. Installing them is so you just go to the website, download those drivers on a path in your system and that's mostly it. There are a couple more steps so you should know if you mention, if you find those on web pages. There is a tool for orchestration those browsers called selenium server which you don't need and there is a tool called phantom.js browser. We will get to it later but mostly it's a headless mode for running browser which renders page but renders it only in memory and you don't have to display application on a graphics server. So imagine we have already installed selenium tool and just like funny and easily we can interact with Python we can interact with a browser we import web driver from a library and we initiate a web browser instance like this one this one. It even notifies us that this instance is being controlled remotely. Once we have it we can issue commands to it and it opens a page for us. Other than that we can find an element on this page and in this browser we give command find element by name and as it is iPython not just a real console shell we can see things here see methods we can use driver, cookies, file detector lots of find element options for you to use. We have this element in a page DOM and we can use it we can just auto-completion Remini and I could not switch window fast enough we are already here let's close it not the element but the driver that was the easy part in this part we briefly showed that we can interact with browser we can find elements in a web page we can find them by their names by their CSS classes we can find a language for querying element in a tree called xpath and by link text for a button or for a href and so we can click all the things and we can type all the things and there are lots of methods to use find element or find elements by something they are actually relying on one internal method called find by find by something which is by id by xpath by selector and all the other utility methods just call to it usually in our internal method we would be relying on this one internal find element or find elements if you want to get this complex xpath selector we can use chrome dev tools find some element here for example this image this is the image in DOM tree document object model tree and for this image we can copy xpath of this element xpath for this image looks like this that's the query any element id is and we can try to use it and it will return us element to work with all the tools we have we have ability to query we have ability to interact with page and that's usually when tutorials stop and present you with future opportunity ok go build things it's easy like drawing an owl and let's try to draw an owl we will be drawing an owl of an application which is a demo for Angular 2 framework when you try to learn Angular 2 they give you a demo which you go through steps and it gives you eventually application called tour of heroes it has a dashboard there are some heroes and you can interact with those things you can open one you can change it you can click save and it will wait a second and go back to dashboard that's what we will try to test I have written a little test case for this and I will go through it here we just initiate a browser and ask it to go to this web page we are testing then ugly thing called time sleep because Angular applications they take some time to load libraries they take time to load assets and if we try to interact with page just after we get there we will get an error it will not work, it will not test it will be fails positive error and it will fail so we will sleep a little after that we test list of heroes we find element by CSS selector model hero that's here when I was looking for it I found this element this div class model hero and this model hero is so we find those elements we look the list is of four elements and that's the first test second test we go the same place we take first element in this list we click on it we again sleep wait for some interaction to happen and we get to details page details page look like this details we can click here and something will happen on this page we find again another element by CSS syntax we find input we send keys just like we did with google and we find element called button with text save we click in it we sleep again and we get to our front page we expect it to have text Dave but in pytest syntax we called driver queued which will close our browser let's test it it opens browser it opens this page interacted, changed clicked and we have Dave to test passed ok great success and now to the ugly part ugly pie was called so for a reason why it is ugly ugly thing here is those timeouts yes just click application take time to load and we have to wait for a bit but when we hard write those timeouts like 2 seconds here, 2 seconds those those 2 seconds are never proper time to wait sometimes the pages take longer time to load there is network latency there is google analytics in your page there is like buttons they sometimes load slow and your page may take 3 seconds to load and this test still should have passed but we have 2 seconds sometimes your web page loads faster it's like half a second and in this case 2 seconds is too slow it takes too much time we should have been just went on your test could have been faster to deal with it selenium provides 2 things first is implicitly wait for all elements to finish so when it tries to find an element on a page it waits for 3 seconds it tries to find it for 3 seconds tries, waits, tries, waits and second part is a bit more complex it waits only for some elements first is easy to setup but I would recommend you not to use it because you don't want to wait for each element to load sometimes when your page is loading it is ok but when your page has already been loaded and you don't change anything if you don't find an element you expected to find it means something is broken you should just show the test has failed and go on implicit is not recommended recommended is just to explicitly wait for some things you want to wait and second part which is ugly about this test it's too repetitive it repeats itself with locators, it repeats itself with pages it is not an easy experience to deal with and writing test must be easy because when it is difficult to write test when it is difficult to understand what it does we should try to do better we should try to design tests which would be easy to understand and easy to extend and easy to maintain and there is a pattern called page object when we try to encapsulate a web page as a python object python objects are great we use them we can extend them we can inherit them and we can hide a lot of logic and details in those objects and classes and they will make our tests better let's take a look how we can use it we have pagespy and we initiate base page we will hide driver instance in it and we will hide waiting for this page to be loaded this will be enough for a moment and our first version will use only this base page just a simple object and a little extension of this base page called dashboard page which will have hero locator to not repeat itself several times and which will have a property which returns heroes after that our test looks much nicer we just initiate dashboard page we open it and we get length and we get text of first element let's try to improve it when we try to improve it our second our second attempt would be to just repeat what we have done with an ugly test let's try to edit things when editing things we will go to another page and ok we will implement this other page also as a page object in our pages we will define class called edit page we will define a method which will wait for it to be loaded we will try to open it and we will also hide some details about this page in a class so we will not be dealing with explicit locator strings in our tests in our tests we will just ask gimme hider gimme name like this our dashboard page it opened it's mostly the same as it was I just hide a name and ID of first hero we click it we go to edit page and we check it is loaded pretty self-explanatory and we check that name is in hider and then the second page second test we load this page explicitly we open it then we clean everything from here type something new save button we don't go into locator string we just type save button click and after that we expect dashboard page to be loaded and first text to be dave let's try it something went wrong let's try it again and take a look at what happens in the browser first test passed ok, second test we had dave we went back to home and it's still narco strange let's try it here we go here tour of heroes, details click save and nothing happens why? I guess we just found a bug in Google tutorial for Angular 2 it worked when we were using ugly test when we went dashboard to the item change, save and it changed but if we went directly to URL it did not work that's a nice test it exposed bug and it also shows we should not combine several things into one test when we combined go to dashboard, click go back it worked when we tried going directly to edit page it didn't it's a nice test we will not be fixing their page right now we will go into details that's one of the things which you should do and you shouldn't do test small things by as small tests as possible one test for one condition testing those small things can get slow because browsers are slow and javascript is fast to execute but slow to load and what I wanted to say it's okay to cut corners here like if you are testing a web application that is an online store or some admin panel which needs login functionality and it would take few seconds each time each of your tests login user you should cut corner here you should not make your users login you should not make your tests login login each time you run something you should there are ways to do it you can just create some quick login URL just don't expose it in production like you go to some URL and you are automatically logged as a user ID something or you can login once and save cookies and instead of really logging in into your application you just substitute cookies header into your browser and test other things it's okay to cut corners a bit controversial advice here but totally logical селениум you can use requests you can use regular tests for jango and flask to test what your API returns is json right or not on what to use xpath or css sometimes css does not cut it but bonus for css is that everybody knows it all the web developers know how to compose those queries so usually use css xpath only when it is not enough there are tools for when you build this framework of a page object you can also implement into it tools called needle celenium has a feature to save a page or save a part of the page and but it's still low level that you should use it in your page object class and in this page object class other people have already done it and you just plug in those functionality in page object class you are building and you can compare screenshots of a page before and after some change and you can see that your web design has not been broken it still looks the same if it was supposed to look the same if it was changed you will need to regenerate baseline images those images you are comparing to some people say that frameworks are just collection of other people hacks and of course there are frameworks around my favorite one is bok choy it's a pun because there was a framework named after some cabbage in ruby language and they were developing a framework for acceptance testing in python and they named it bok choy it is nose based framework which extends Selenium and implements needle and implements some other nice helper tools I used it and I liked it but there are other notable piacenter a bit unmaintained and a new one called webium from Wargaming company and that's mostly it thank you I am now welcoming your questions we've got time for some questions we have a microphone please raise your hand if you have one thank you very much for your talk when do you choose to use Selenium and when do you choose to do the requests tests if we are working with browser things if there are mechanics that happen in a browser javascript you have to use Selenium if there is only check for some element is present in an html of a page some element is present in json response of your web server it is easy to check with requests and requests are 100 times faster than Selenium those things should not be sent to a browser it will save your life hello thank you for your talk I choose Selenium it has a big web application problem I had there when I obviously used wait for element it found this element and the problem is that wait for element is not an atomic operation which means that if another thing on the site changes in the meantime it would put the virtual cursor at the location which would then be invalid and it would click an image that loaded in the meantime so obviously I can't wait for all the elements because there might be javascript that constantly loads things so what do you do in such a situation where your site layout might change and you don't like it's not not too monistic that it changes and you can't really wait for everything to stop getting data what do you do in such a situation I have showed in my test exactly this question I had when Angular views are loading some elements and then they build a structure in those elements inside maybe they don't load all other things all images all styles we don't wait for them key is to understand which element has to load in your document object model like on our first page if there is a list of heroes present we can assume that the page has loaded if on the second page and the input on this page we can assume this page has loaded and we can start interact with them thank you very much for the talk I also have a question about two questions actually about Selenium I'm abusing it to run nagius checks so I'm constantly running like every five minutes running login checks and web applications and what problems I've had are one, the driver doesn't die so when I quit or close Selenium I can see dead processes I'm not sure if I'm doing something wrong or why the web driver process isn't dying on machines that's just a feature of Selenium driver it doesn't close your browser automatically you have to call quit explicitly if you want it to close and also I can recommend if you want to run this thing continuously on your server you should try either running a phantom.js like here when we were just initializing driver web driver chrome you can initialize web driver phantom.js or you can initialize chrome with some options and it will run in headless mode it will still pop up application but it will not require graphic server you can run it on EC2 instance elastic computing, amazon instance you can run it on linux server without display at all it will consume much less memory and you can have it running constantly and it sounds good the other problem was that it was filling up my temp so when the browser died it was leaving artifacts in the temp so I could see the memory usage and the machine rising and also disk usage so it was leaving behind in the temp directory quite a large chrome footprint so what I was doing I was just chronic deleting the processes and but I guess then you have to write your launcher script which would clean up after that and kill instance if it does not die maybe you have outdated Selenium driver with some issues or maybe you have outdated browser thank you thank you for the talk I wanted to ask two questions if I can the first one about you had error in Angular which prevented you which raised the failure I'm assuming that's a javascript error so is there a way you could return that trace back for instance for that javascript failure from dev console of chrome or maybe from the headless driver and the second question I have is which versions of chrome does the web driver support and basically who maintains it is it something from Selenium external can you write your own drivers thank you Selenium does not give javascript trace back unless you set up something in your page which would but short answer is no Selenium does not give you trace back Selenium just indicates the problem but by the way when you mention it when you build those page object classes exceptions for you to use Selenium exceptions are I haven't found something I could not locate an element but you when you expect those things to happen in your page objects like locate a search box or try to type something there you can raise your own exceptions and they might be more convenient for you and make debugging a bit easier and also when Selenium meets a page which is not some element missing but full blown Django exception yellow page database could not connect you could also detect the situation and raise more meaningful exception not some element was not found of course there was not element found on that yellow page that Django raised textual exception from your use case and for a second question who maintains it Selenium is maintained by open source company Source Labs and Selenium and those things Selenium interacts with browser using protocol which is open which is W3C standard JSON over HTTP and those little things which take requests from Selenium and translate them into browser actions called web driver drivers and the best part is that they are maintained by browser vendors Google themselves create a driver for Google Chrome with driver for Firefox We don't have more time for questions you can of course ask team afterwards just remember that from the app you can vote you can rate this question you can also add comments add some feedback that can be useful for team for future talks so please and clap your hands again for team