This is browser eyeballing is not equal to JavaScript testing obviously we're going to be talking about JavaScript testing. My name is Jordan Casper you've got my Twitter handle up there on the screen as well as a link to these slides they're online now they will continue to be online feel free to follow along hit them up afterward there's a bunch of links throughout the slides so you might want to do that bookmark that so that you can refer to those links afterward brief introductions I work for a company called a pen to I'm a senior JavaScript engineer there as well as a team lead so I work in JavaScript literally every single day we build a lot of really heavy front-end client applications but we also do a lot of node development we do a lot of code reviews of existing JavaScript applications we do a lot of responsive web design things of that nature I have been coding since 1993 I've been coding JavaScript since about 98 in the dark times and feel free to hit me up afterward if you have any questions even not related to JavaScript testing so what we're going to talk about today first of all we have to talk about writing testable JavaScript code most people that want to test their JavaScript are not actually writing testable JavaScript code you're writing code that is nearly impossible to test on an individual basis right we don't want to be testing your code end-to-end every time a lot of times we want to test individual functionality in order to write those unit tests you have to write your code in a way that is actually testable so we're gonna talk a little bit about that obviously we're gonna talk about talk about setting up a testing framework and I'll mention a few frameworks we're gonna pick one just for the sake of time and ease of demonstration and then obviously writing tests and a little bit on automation at the end and if we have time depends how fast I get through the material and how many questions we have I've got a little extra content on automation so we'll see how far we get with that but we'll at least cover a few basics so I'd like to know how many of you identify with this testing process you write some JavaScript code and you look at it in Chrome or Firefox or whatever you want to test it in it looks pretty good then you write something else and you change it and it breaks and then you spend a couple hours fixing it and you just basically do that over and over again right and then you test an IE like two months later and and you realize that it's not going to work and the real problem isn't that you're testing an IE two months later necessarily the real problem is that you have no idea what the problem is you don't know if the issue with your code is your code or if it's that Internet Explorer is Internet Explorer and that's kind of one of the one of the biggest problems is you don't know and so what we're going to talk about is writing tests that will actually test the functionality individually in your code and not necessarily your application end to end which obviously is important as well but is a completely different topic so first of all we need to talk about the better way to write your code so we need to talk about writing testable JavaScript code and this comes in many formats I'm going to put up a sample of code here and I know it might be a little hard to see in the back but we're going to break it down and go to individual sections very simple little piece code it's using jQuery but that's not the important part the important part is just the general functionality so what's happening here is we've got a little input and when the user submits the form that the input's in instead of doing a typical submit form submit we're going to do an Ajax call for some search results get back to search results and dump them into an unordered list it's pretty basic functionality some stuff that you would probably do you know a hundred times in an application right someone type something in you do an Ajax call you get some results you dump it into the page pretty basic so you might look at that and say well you know what's so bad about that well let me strip out some of the internals and just show you this part and I've bolded some of these lines here and what I want you to under to recognize here is that each of these bold lines is a function and if you'll notice we've got one kind of top-level callback function when the document is loaded when it's ready and then you've got you know when the submit occurs and you've got when the Ajax call comes back and then you've got a for each looping through the results to put the results into the page so we've got functions inside functions inside functions inside functions and the problem is every layer that you go down there is no way to test that there's absolutely no way for you to test any of those inner functions by themselves zero ways to do that you have no reference to that function and thus you cannot call that function outside of this execution context and that's a really big problem but in addition to that you'll notice that all of these functions are unnamed and so this is what you get in your call stack when you get an error you look in dev tools or f12 tools or whatever you're using and you see anonymous anonymous anonymous anonymous anonymous because none of those functions are named they're all in line declared in line so beyond just testing the code you can't even see where the problem is so we're gonna talk about that we also have some really tight dom coupling here and you might say dom coupling well I'm in a web page of course there's dom coupling but JavaScript code these days is moving more and more toward a separate execution or not execution environments but separate context so you've got whether you're doing some kind of MVC model whether you're doing MVVM or whether you're doing whatever it is the idea is that you've got a bunch of business logic and you've got a bunch of view logic and mixing those two is going to be really bad first of all it means you're not going to be able to reuse your code second of all it's going to make this testing really hard because in this case I have to have elements that have search hyphen form as an ID and search hyphen query and search hyphen result if those elements don't exist this whole thing fails the whole thing fails so instead of doing that when I want to test individual functionality I can pass in those required dom elements and say hey use this element for the search and use this element for the results so we want to decouple our business logic of performing the search from our view logic of displaying those results or capturing input from a view and we also of course have some server coupling here where we've got this Ajax call that's going to go and get the results from the server and the problem is well I personally when I do JavaScript work I'm not working with a server I hardly ever work for a server I work in professional services so I've got a client that wants me to write all the front-end code and they've got some back-end that who knows what's it what it's in but they've told me what the API is and the problem is I don't have their application running on my local machine so how can I test this code without having that service so we're going to talk a little bit about that and how we can test these things and get get around some of those those coupling issues so of course the solution is to refactor this code so we're going to take that code and we're going to refactor until it hurts and then you're going to refactor a little more and I always tell people because they always say well that's a lot of code to refactor there's a lot of things going on there obviously this is a simple example there's still a lot to refactor but you've got to take it incrementally you've got to say well I can pull out this function name it give it its own context and then inject that function you can do this in an incremental fashion such that you're refactoring the most risky parts of the application and just moving forward from there maybe you can't do the DOM uncoupling maybe you can't do the server uncoupling for some reason but you can take an iterative approach to this so just really simply we can break out all of these functions there's absolutely no way that this could really harm your application we break out these at these functions into named functions now notice I've given it a little namespace here window.jk and no I'm not kidding that's those are my initials and so you've got window.jk and now I can put all of my methods onto this namespace of course you might be using something else you might be using AMD modules you might be doing require.js you know whatever the case may be you break those things out in this case just to a simple namespace so now I've named all of these functions and I've also given them inputs and we're gonna talk about those in a second but just by doing this I now get this is my call stack now I'm still there's still all some minified file and it's all on line three because I've got my banner comments and then it's all on one line and you know whatever that that is what it is but at least now I get the call stack and I can see the execution flow when an error occurs so that's one huge benefit that you get just in debugging so this is my initialization function right so I've got some initialization function and now if you'll notice I've got two inputs so I'm gonna accept the form which I need to attach a handler to and I'm gonna accept the input which I need to get a value from so I'm accepting these things as input into my function and then of course I add my submit handler and then inside the submit handler all I'm gonna do is grab the value from the input that you gave me and pass it off to my do search method so that's all that this thing does and I can test that all day long all I gotta do is make sure that do search gets called and then it gets called with the right value when a submit occurs that's really easy to do really really easy notice here on my submit handler it's not just function open parentheses close parentheses open bracket close bracket I've given it a name your inline functions do not have to be anonymous I get people in every single session they come up after like I didn't realize you could do that any function can have a name even inline functions like this can have a name and what does that do well if we go back it does this notice in my cost tech here one of them is submit handler so I know oh it went through that function great I know that went through there name these functions there's no reason not to name them you might argue oh well that's an extra what is it 12 characters who cares 12 characters is not going to matter these days I'm sorry you might say oh well if I do that for every function I get well first of all you probably shouldn't have that many inline functions so you're going to be naming them anyway aren't you because that's how we're going to test them it's really not that much more and if you're going to minify an ugly fire code then it's really not going to matter because they're going to get shortened to one or two characters anyway you also need to of course initialize this so you might notice that I skipped over the document ready function but now I've got it so when the document is loaded I'm going to call this initialization function and notice that I pass in the ID for my form in my input so again I'm passing in those this might be on the HTML page but I don't have to test that that's not what I'm testing that the document gets loaded that that's not what I'm testing what I'm testing is that the initialization function for my search functionality works so completely separating the loading of my document and kickoff from what happens on kickoff so I can test that independently the do search method is is pretty much what you would expect all it does is accept the value and it calls our our Ajax endpoint and has some success and error handlers notice that my success and error handlers both are named functions they're not going to do very much they're going to be really lean all they're going to do is call some other function but they are named so I can see that execution flow notice also that in my arguments I accept both the value that I want to search for but I also accept a callback function that's going to be really important if you're using promises that's only fine you can return a promise from this function but you need some way to know that this thing finished because it's an asynchronous action and we can only test it once that asynchronous action completes we're going to get to that when we get to our testing framework so I mentioned in my Ajax call in the success handler all it's really going to do is call handle results so I call handle results with the data returned from the Ajax call was that let me do well first of all I can call handle results from anywhere so I could do it on document load I could do it on search I could do it on some other related search I can do it any time I need to because that functionality is completely segmented and isolated and I can test that that functionality and that functionality alone works in the error handler of course you know I might do some kind of pop up but notice in both of those cases I have my callback function that gets executed that callback function is what's going to allow me to test that this functionality the do search method actually worked handle results pretty basic I'm going to pass in the node but you can see I might do something like well if you gave me a node to put all these results and then I'll use that and if you don't then I'll assume that you've got some idea on the page kind of let's you simplify the code in your production environment but in your development environment you can say oh no I'm going to inject this DOM element that I want you to use that's in my test harness and of course I still look through the results I still dump them in but now I've got a much better idea of what's going on and I can test just this functionality see what happens there. Okay so you're going to need to refactor all of these things but there's more that you could refactor in there I touched on some of the big things but you can refactor so much more out of that and make it really really highly testable. So let's talk about the testing frameworks obviously this is really why we're here there's a lot of different testing frameworks these days I'm not going to be able to cover all of them this is not a talk about different testing strategies per se this is a introduction to JavaScript testing these are the frameworks that are probably the most popular right now I've used all of them however for today we're just going to focus on one that is a little simpler to digest when you're new to JavaScript testing so we're just going to focus on Q unit Q unit was is a testing framework those have developed by the jQuery core team they created it to test jQuery so this is what they use currently and it's a very simple introduction to testing it does not actually follow the X unit path so if you're familiar with PHP unit it doesn't really follow that paradigm exactly but it is very similar more so than these other frameworks. Just for those that aren't as familiar with testing in general we're going to have some kind of test suite it's actually called a suite in Q unit but let's pretend like it is and inside of that you've got some grouping of tests in Q unit called a module and inside of modules you've got multiple tests and inside of tests you'll have multiple assertions so these things are all nested and we can execute them at different levels. Setting up Q unit is really easy obviously you're going to go and find it download it or you could use something like Bower to install it. This is a typical Q unit HTML file this is not a snippet of the file this is the entire file that you could potentially need to run your Q unit tests. I know it's kind of hard to see in the back but let's look at it individually so in your head you're going to have some link to the Q unit style sheet this is just so that the results are pretty and don't look terrible. In your body you're going to want to have or you could do it in your head you're going to want to have the script tag for Q unit so this is the actual test library just put those anywhere really. Inside of the body you also need two divs these are required and they do have to have an ID that matches these IDs on the screen the first one is just Q unit and the second one is Q unit hyphen fixture they do have to be just like that that's the first one Q is where Q is going to put its user interface so the results being able to rerun tests things like that I'll go in that Q unit div. The Q unit fixture is where we put HTML that we want to be available to each test and to be recreated for each test. So you dump some HTML into the Q unit fixture and before each and every single test Q unit is going to reset that HTML to whatever it was when the document loaded. So that's pretty nice if you need to just throw in a UL for our test results and a form and you wanted that form in those test results to be reset before each test we dump that HTML into the Q unit fixture and you don't have to worry about it you don't have to worry about resetting it yourself. Of course we need the script tag for our source code so whatever that that is you need to include that as a script tag and you need to include a script tag for your tests you could just put these in the page in line I actually see that pretty frequently I like to separate it out to a different file so that I can include those tests in different suites if I wanted to. And that's it that's the entire HTML file for your Q unit suite so that's that's our test harness that's our suite that is what comprises a run of tests. So in the test file obviously you know your source code is whatever your source code is in the test file what do we have well we have something like this so if you remember my source code I've got the namespace there and our initialization function and then in my test file I'm just going to have a call to the test function notice it is globally available you can also access it off of the Q unit namespace you actually see this more often it's that's why I put it up here because it's very simple the first argument is the name for this test pretty basic the second argument is a function that's going to get executed when this test runs so that function is going to execute when this test runs and inside of there I've got two assertions they just use the okay assertion so I just call the okay function and the first argument is some truthy or false value so in my case I'm passing in JK the namespace and all this test is is that value truthy so an object is truthy if JK were undefined this that assertion would fail but since JK is defined as on the window as our namespace object that test that assertion will pass the next assertion says hey is the type of in its search a function if it's a function that assertion will pass my whole test then passes and I'm good the second argument there to this to these assertions is just a message it's not a success or a failure message it's just a message that identifies that assertion that's really it does it not success not failure people kind of get caught up on that it's just an identifier so if I were to run this html file that I showed you earlier and just load that html file in a browser I don't have internet access so this normally runs very smoothly I'm sure you're going to get a UI that's just going to identify all the tests that passed it's going to identify things like the browser agent that it ran under how much time it took how many assertions were run how many assertions passed things like that let's see if this iframe will load so this was actually a live iframe on my site to see those results and that's not going to run so I can't show you that qi but the thing is you don't want to do that anyway you're going to want to run it somewhere else you're going to want to run that in some kind of automated fashion which is what we're going to get to in a few minutes just real briefly when you see this interface all you really get oh there goes okay so what you'll see here is all the stuff that I just told you and then you see that that first line is our test it says namespace exists which was the name of our test and you can see some little numbers next to it which basically tell you how many assertions were run how many succeeded how many failed yellow green bars next to them and yay everybody's happy right if we wrote a failing test this is what you would see notice that it automatically opens up to the failed test the or failed assertion excuse me and the failed test the first assertion passed so you get the little green bar on there right at the top there and then it tells you that one failed it tells you what it expected what actually happened and it gives you uh the diff and the source so you know exactly what test where what line in what javascript file that test is located so you can go and look at it and figure out what failed so this is the the q-minute browser ui this is what you see when you just load that html file that i showed you earlier in a browser there's your test and you're done that's it yay testing of course there's more there's lots of assertions so i showed you the okay assertion that one's pretty easy truthy falsi right and then there's equal and not equal and that takes three arguments not two so the first argument is what you i believe the first argument is what you expect or what actually happened the second argument is what you expected and then it shows you the diff of course it doesn't really matter because all it's doing is comparing those things right so obviously equal not equal pretty obvious you also have strict equal and not strict equal which is necessary because javascript interprets strings and numbers to be the same if they're can kind of be coerced into the same type right so strict equal and not strict equal will enforce that strict equality deep equal and not deep equal are useful in limited cases please do not ever use deep equal for some complex object that's a really bad idea if you have a simple list of properties sure fine deep equal is fine for that do not try and use this for comparing the window object to something else it will bog down your tests it will run forever and it's terrible not deep equal obviously just the the inverse of that and then we've got throws throws is actually really nice if you use exceptions if you use the error object in javascript in your code and you need to know that when i pass in a bad argument to this function it should throw an error you want to use throws throws will catch that error and say okay this assertion passed because it threw an error because that's what you expected to happen otherwise that error would get thrown to your test harness function here and then it would get you know thrown back up and your whole test would fail right so if you've got errors that you know are going to be thrown and you want them to be thrown use this to capture those and you're all good notice that this takes a function right so you take that function and then you can do assertions within that throws block if you wanted to so we're going to write some more tests first of all we've got our initialization function right and so what we might want to check on for our initialization function is that our submit handler is actually there because that's one of the primary things that the initialization function does right is it attaches that submit handler and then passes off the value of the input to the do search method so that's easy in jQuery you can do this there are actually ways to do it with core javascript but i'm already in jQuery so i'm just going to use it and this isn't a class about how to get event handler names off of the DOM object so in jQuery you can just do this where we've grabbed the search form that we know we passed into initialized search right so we passed in this search id and then we're going to go grab that id and grab the events off of it and look through those events and say well is there an event handler in there called submit handler so we're actually verifying that our submit handler was attached correctly it tests a couple of things but you can see the benefit there that's the primary function of our initialization function so that's what you want to test a lot of people wouldn't test something like this but oh well of course the event handler gets attached and then your test fails and you don't know why your handler function never gets fired and you're like why does my event handler function never get fired well because the event handler was never attached so this tests that first and then you can test all the other stuff so for my handle results method i might want to say well i need to make sure that the case where there are no results is handled correctly so i can call my handle results method call it with an empty array remember this is completely detached from our ajax call completely detached so i can call it with no results and just ensure that in the search the results node that i have the right text so uh maybe i'm supposed to put there were no results into that node maybe not maybe you're supposed to do something else maybe you're supposed to throw an air and you could do a throws block here but whatever you're going to do you want to make sure that you're testing all those cases test that you get an empty array test that you get one entry in the array test that you get multiple entries in the array test that you get more entries than you expect to display you know if you're expecting to display 10 and you actually get 20 back what do you do do you just display all of them is that really what you want to do make sure that you're testing all those things and you can do all those things with these assertions so i want to talk a little bit about grouping tests and then we're going to talk about asynchronous test which is super easy actually q-knit allows you to do this and so do all of those other frameworks by the way all those assertions i just talked about all the other frameworks have assertions some of them are named slightly differently but they're all very similar in q-knit we use test modules in something like jasmine or mocha you use describe blocks so they're all very similar you just give that block a name so in q-knit we call the module function and we pass in a string that identifies that module and every call to the test method after that those tests get put into the module above it and so as soon as i make that second module call right here as soon as i make that second module call all the tests under there are put into the immediately preceding module so that's how q-knit groups those and if we look at that in the ui you can see that our test runs here are actually it might be hard to see in the back but so it identifies the module name first and then the test name and then of course the results one thing that q-knit also does is in the top right corner there you've got a nice drop down and i can actually rerun individual tests or individual modules excuse me so i can say oh rerun all the modules for x or all the modules for y are the test for module x all the tests for module y so that's just a very simple grouping mechanism but it also also allows you to do things like life cycle functions so basic testing life cycle which is true in q-knit and true of most of the other testing frameworks that i mentioned you have something where you've got some start of the whole suite you've got the start of an individual module a start of an individual test and then of course you've got all the assertions that run and once all those assertions finish you have the completion method for some tests the completion message method for the module and then the completion method for the suite as a whole and q-knit allows you to tie into each of these events so in your test harness or in some external JavaScript file either way you can add a q-knit.begin call right there and pass in a callback function so that callback function works cute as soon as q-knit begins running your tests so if you need to initialize some stuff you can do that in there and as soon as that function finishes then your suite keeps going and of course you can do that with module and test levels as well when q-knit finishes you can do q-knit.done this is really nice for doing any kind of logging maybe you've got an external test log server that you need to say yes this test passed that's where you're going to do that and in fact when you start doing continuous integration with javascript tests that done function is how you tell the continuous integration server yes all of my tests passed and perhaps you know here's the results whatever you need to do as i mentioned you can do module start and module end and notice that the module done function there that callback function accepts the name of the module how many tests failed i'm sorry how many assertions failed how many assertions passed and how many assertions there were total so you can actually get a lot of the statistics in those done functions in order to do that logging that you need to do test start and test done pretty much the exact same way although test done also gives you the name of the module that you're in so most of the time when i see companies that come to us and say oh well we can't test our asynchronous stuff in isolation because you know it's got to have a server well first of all it doesn't it's not that hard it's actually really easy and of course it's not just ajax calls right there's other asynchronous stuff that goes on it might just be an event handler that gets fired it might be that you've got some set timeout or some interval that you want to make sure is actually executing when it's supposed to be executing there's lots of other instances where you might have asynchronous code that is going to be difficult to test and you might say why is it difficult to test well when we have that test function that text function is going to execute all of your assertions in order and when it finishes it moves on to the next test and it reports when that function finishes it reports to queuing it hey all these assertions passed well if the function finishes and it was asynchronous there was some there was some action in it that was asynchronous then guess what your assertions haven't executed yet by the time the test function finishes and so what does it tell queuing it i didn't have any assertions to run that's a problem first of all it's a problem because queuing it might fail silently because it would say okay well you didn't have any assertions so zero of zero assertions passed that's a hundred percent well done not really what you want so we need to test all of this even the asynchronous stuff and how we're going to do it is really easy so there's our do search just to refresh your memory we've got this ajax call it's got a success in an error handler we start instead of with test we start with async test you can actually just use the test method as well and you can call a start method when you call start the start method or when you initiate an async test it tells queuing it hey i'm going to do some async stuff so hold on and it waits and it lets you do your async stuff so we do our our our call to do search and when do search returns remember we've got that callback function that we added so when do search completes when that ajax call is done we call this callback function we either get results or we get an error whichever one we're expecting we do our assertions on that so maybe we make sure that the results are what we expect maybe we make sure that an error was actually returned to us whatever the case may be and when all that's finished we call uh oh i'm sorry we call start stop would be the function you call to stop it obviously so we call start and when you call start you're telling queuing it okay i'm good keep going and now queuing it says okay let me see how many assertions were run now how many failed do i need to fail that test do the reporting stuff like that super super easy to do asynchronous testing and all of the other testing frameworks have something like this it's really very easy do not ignore your asynchronous functionality when you're doing testing but you don't want to rely on a server right it's hard i got i've got this server and i don't want to have to have it up and running locally i don't want to have to have a test server up and running your javascript code doesn't care about your server at all but i think well but i've got ajax calls and the ajax calls care about the server no they don't the ajax calls do not care about your server all they care about is that your handler functions get called with the data they expect right it doesn't matter that the ajax call actually happened or not what matters is that you get the right data into the function and so what we need to do is mock out that stuff and here are a number of tools for doing so if you're doing jQuery you can use jQuery mockjax which is actually a product that my company wrote if you're doing jasmine tests if you're running with jasmine jasmine ajax if you're doing angular you can do it with the angular HTTP back end using ngmock if you're not using any of those and you're doing a custom framework and you're not using any other outside framework you can use synon or sign on the founder actually pronounces it both ways i don't know why and it does a lot more than just mocking out ajax requests it will also do full dependency injection it will do spies function spies so there's a lot of different things that that that tool will do it's a pretty robust tool all of these tools are going to let you completely isolate your front-end code from your back end by simply capturing those ajax calls and saying oh i'm going to capture it no don't go to the server instead just respond with this test data i actually have a blog post up if you just google my name you can go and find it i just posted it like two days ago no yesterday just posted yesterday on how to mock out a server for JavaScript testing so feel free to go and find that i don't have time to go into all the details of how to do that but look at these tools they're really fairly simple to implement this is just a simple mockjax call all you can see here is that you just match a url right so the easiest way to use mockjax is you just match a url and you have this response text it just says hey when i hit that url instead of going to that url just respond with this text string and you can see that's a json string so it will respond with the stringified version of that json object and return that to your callback function never hit a server completely isolating your front-end code from any server that may or may not exist and allowing you to test in an automated fashion with exactly what data you want to test with zero results one result multiple results errors 404s 200s whatever so again just a simple simple view of that so i'm going to move into how we're going to automate some of these tests so obviously loading up all of these tests into a browser and just sitting there and hitting refresh after you change some code is really really really annoying and we don't want to do that we want to automate this first of all you can't load those browsers up and do that with a continuous integration server and expect any kind of performance it's actually really really difficult i used to do it in the dark days 2005 when that's all we really had because we didn't have automation tools but now we do and the automation tool we're going to use is grunt there are a couple of other ones i'm talking about grunts we can debate the other ones after the session if you wish now grunt is actually a node module so in order to use grunt you have to install node so go install node and then after that you use the node package manager which gets installed with node in order to install grunt the first thing that we're going to have to do to set up grunt though is we're going to have to create a package json file this is a node construct but don't worry we're not doing no development we just need to use this to tell grunt what we need so this package dot json is about the simplest you can get all you do is give it a name and a version for your application and then this dev dependencies object so it's just a json object very simple mapping of what dependencies you need for development now the only one that we need is grunt right now and so what we're going to do is we're going to go to our command line no one run away said command line and we're going to install the grunt command line interface using this npm install dash g grunt dash cli the dash g flag there just says to install it globally so this gives you the ability to run grunt from your command line that's what that does the second line actually installs the grunt execution environment in your project so npm install dash dash save dev puts it into your package json and now you've got grunt installed for your project as well as the grunt command line interface for you to actually execute those on your machine and again refer to these slides i'll have a link to them at the end just go through and do these commands i promise they work they work on windows mac linux so now you need to create a grunt file the grunt file is what's going to tell grunt what tasks you want to execute grunt is just a task runner it's it's a framework you have to tell grunt what tasks you want to run this is really a boilerplate file i use this file and i just basically copy and paste it over and over again in each project and then we fill in what we need what tasks we need for that project you can really ignore almost everything all you really need to know about is what's in this to-do line here and then we're gonna have to load some modules here at the bottom so grunt tasks are anything they're literally anything copying files concatenating files minifying files appending files testing files uh pre-compilation steps for sass image optimization there's all sorts of things that i've used it for can really do quite a bit and you can write your own stuff it's a node module and node is on the server so you have full access to the file system you can really do anything with it we're going to install one plugin for grunt a grunt task and this is the qunit runner so this is the thing that will actually run the qunit test for you you can see that we've done that dash dash save dev flag again remember that puts it into our dev dependency so you don't have to touch your package.json file anymore it will automatically update that for you and it's grunt dash contrib dash qunit that uh contrib piece right there that tells you that the grunt core team is maintaining this package and that kind of gives it a little bit more credence um if you see one that doesn't have that you might be like i'm not sure about that one and maybe try and find one that is a grunt dash contrib so that's the task that we're going to use so we've installed uh so we're going to we installed that script and now we're going to go remember i had that to-do line in our grunt config file or our grunt file now we're going to add this task so this is just a json object in right where that to-do line was so the top level is our task name qunit that's defined by the plugin that you install so qunit it has to be called qunit can't be called anything else that second level though where it says basic that's a target name the target can be anything you want to call it whatever you want to name it you can name it whatever you want i'm just saying these are our basic tests you might have uh search tests and user tests and authentication uh you know some other footer tests and menu tests and tests for all different parts of your javascript code and those could all be different targets inside of your target you've got different options so i've got that options block and inside that options block i specified the urls that i want to test so remember qunit runs inside of an html file right so i have to tell the qunit runner what url i want to load now notice i've just given it a relative url so relative to where my grunt file is you can find the html file the one that we created earlier at this location so grunt is going to load up that html file and execute your grunt your qunit test for you and i uh one last thing at the bottom here notice that we've loaded the npm module so remember everything's running through nodes so we had to load up that module and it's just the exact same name as the plugin that we installed using npm you just add a line for each task that you add and i also want to point out one thing you can kind of strip this down the qunit plugin doesn't have a whole lot of options out of the box you don't need many so a lot of people will condense it so i've still got my task name qunit and i've still got my target name basic but then i've just collapsed everything else into this one array of files that i want to test you actually see this format much more often and remember notice that that's an array so i can add multiple html files there right we'll get to that so i've created this grunt file you might be saying but i can't run them from the command line qunit runs in a browser so what do i do there is no browser right you're on the command line you're not going to open up a browser but you need a browser so what we're going to use is qunit in combination with phantom js now when you install the qunit grunt plugin it installs phantom js for you you don't have to do this separately phantom js is a headless headless there's no visual representation everything is running through the command line you might say well that's not really a browser it is i promise it's really a browser it has a window object it has a full document object model it can run javascript it can render css it is a full browser you just don't see anything what that means is all of your javascript tests and all of your javascript code can execute just fine inside of it it can position elements within the window you can check their position using javascript you can render css and make sure that that css puts things where you expect it everything you can do with regular browser you can do here just on the command line which means it runs really really really really fast and you don't have to worry about spawning new browsers when caveat it's one browser right it is one browser and you probably want to test multiple browsers i'll mention that at the end so i'm going to go back to my command line and i'm going to run my tests so i execute the command grunt which got installed with the grunt cli that we did earlier and then i specified the task and then a colon and then the target so remember there's task and target there's it's a nested structure here so execute grunt cunit colon basic and it says i'm running cunit basic for you and it says i'm testing core test slash core dot html and then it's got a couple of dots that's not an ellipsis the dots are not ellipsis each dot represents a test that you're running so each dot is a test and at the end you'll get this green okay and at the bottom you see done without errors and it tells you how many assertions run and how fast notice this ran in 21 milliseconds you think that's faster than you opening up a browser and hitting refresh probably and that's it really easy command line integration for your cunit test and now you could execute that command from any other continuous integration tool you might have whether using jinkins or travis or using fing or whatever you're using you can execute any command from the command line using any of those tools if you get a failure this is what it's going to look like in your terminal it's going to get a big red f instead of one of the dots and it's going to give you the message and it's going to tell you what the actual value is what the expected value is and it'll give you a stack trace from the test file all the way down to your source code yada yada yada and then at the bottom you get this aborted due to warnings and that's really what you want to see or what you're looking for you don't really want to see it you don't really want to see it we can add multiple targets remember i mentioned it's a nesting structure so i've got cunit and then i can have basic and i can have search so i can have different levels here as i mentioned those are arrays so i can tack on extra html files and test multiple but you can also use a globbing pattern so i could say for the search it's test slash search slash asterisk dot html find all the html files inside of that subfolder and execute all of those so you can really set up really complex groupings of tests here so that you only want to test these things i only test those things etc etc i mentioned so you saw this this is how we ran our cunit basic if we want to run cunit search we would have to do grunt cunit colon search however it's a nested mechanism so if i just ran grunt qunit it would run all of the targets so i don't worry about that and if you add it to your default task then you can actually execute just grunt and it would run all of the tasks that you have defined as default if you are really interested in grunt there is a talk tomorrow does anyone know i think it's tomorrow on grunt it's today thank you so there's a talk later today on grunt i would highly highly recommend it if you're going to do anything with JavaScript testing because this is the de facto standard for automating your your JavaScript tests and i'm sure that talk will go into much more detail on how to configure grunt which i don't have time for there you go 345 room 17 thank you very much so that is the end of the primary content and i wanted to go on to some extra content if you're willing and i'll come back to this slide so you can get the link there and the link to review it and such okay so i wanted to make it a little bit easier for you because you still got to go back to the console and run grunt cunit and then go back to your code it's kind of annoying right so let's let's make that a little easier for you we're going to do that with the watch plugin the watch plugin does very much what it sounds like it watches things so first of all we've got to install it so this is exactly like we did before right npm install dash dash save dev grunt contrib watch so you know it's maintained by the core group of grunt yay and then we've got to configure it so we create a new task in our grunt file dot js the task name is watch and notice that our target is js and of course you could watch other files right you could watch css files or sass files you could watch html files you can watch whatever we're watching uh our target name is js and what we're watching is in this files list so in the files list i've used this globbing pattern to say go to my source directory and use the double asterisk to go to any sub directory within source so any sub directory any level down go into any of those and find any file with a js extension so that is going to watch all of the javascript files in our source directory and there's the tasks array and it says okay when any of those change execute these tasks and notice i just got queuing it but i could say queuing it colon basic or queuing it colon search so when this subgroup of javascript files change run this subgroup of my tests right so i've added the watch plugin don't forget you have to add the load npm tasks lying down here at the bottom of your grunt file so now i've added the watch task let's flip back over to our console so in our console i'm going to run grunt watch and it's going to say okay i'm running the watch task and then it's going to say waiting and it'll just sit there and it waits so this is my workflow like day in day out this is my workflow i've got two screens right and i've got my code on one screen and i've got this in a terminal on my second screen and i run grunt watching it sits there and waits and then i just code along happy as ever i make some changes to a javascript file and i save that file and as soon as i save that file it says oh i noticed the file changed and it runs my queuing it tests and it says done without errors and notice at the bottom it says waiting and all i do is i glance over i see green and i keep going and as i'm going i'm continuously testing my code and as soon as i make an error i get the red aborted due to warnings it continues to wait i make some other change to revert what i just did because obviously i broke something and then it runs my test again it says up you're back to green and you're good very very very easy to do continuous testing on your javascript code without any external server without any with just very minimal tools and of course you can integrate this you wouldn't integrate grunt watch but you can integrate the execution of those tests with any continuous integration tool that's out there right now briefly i want to talk about cross browser testing because obviously as i mentioned we're only doing testing in phantom js and that's one browser and one browser alone and that's pretty pretty bad you want to test across a lot of browsers in order to do that there are a lot of tools for it these are just four of them i tend to use sauce labs right now what's nice about sauce labs and actually browser stack has this as well is you create an ssh tunnel to the sauce lab server and you have a configuration file that tells sauce labs hey i want to run my tests on chrome 29 and firefox 96 whatever it's on ie six seriously they have ie six and they execute all of these tests in virtual machines on their servers and then just report back to you the results and you can actually do this through a grunt task so you could actually watch your files and then kick off a sauce labs a test run from your command line test across all of your targeted browsers and get back those results in your in your console just from your local machine without having to have anything else very cool test them actually runs on your machine it will spawn real browser instances on your own machine which is nice except if you're on mac you can't do ie and if you're on windows you can't do safari well not real safari anyway and then you've got of course a the other player selenium selenium has a remote web driver so you actually set up an external selenium server and you have tests that hit that server and it reports back results and that's it's nice but it's a little more setup browser stack has a browser stack has a similar tool to sauce labs you can create ssh tunnels and open things up on virtual machines so that's it for cross browser testing tools let me go back to that our slide here and i want to thank you for coming and i want to open it up for any questions on job script testing if you are comfortable please come to the mic if not i will just repeat your question for you go ahead i just just yell it out all right so pulling in external vendor files is always tricky it doesn't matter whether it's truple or anything else honestly if they're if they're external job script files that you have to get from some vendor source unfortunately right now the best way to do that is to actually pull those into that html file the community html file and just reference them however you can you could actually you know you can generate that test html file using truple i mean you could have you know a structure for that and it could it could have your common header and stuff that pulls in all those files we actually had one where we were generating the html files using node that the test html files using nodes so that we could inject the script tags and the html from partials so that's generally what i see done is you just pull all those vendor files into your test suite yeah with truple i would actually say maybe try and generate those html q to html files using truple and you could always just have a copy of the javascript files and just do it that way yeah thanks thank you very much for your talk today can you talk a little about a situation when the javascript response might be personalized based on and the user session yep absolutely dealing with so what i would say is your javascript tests don't care about your user session they really don't care whatsoever if that data is in the javascript namespace that you're using then there isn't a problem because you just artificially fill that namespace those namespace objects when your test begins if you're having to hit a server to get that information back i would say mock out that server and instead of returning real results you return john doe every single time for every single test it's always john doe and then you can test that john doe appears in the header and that john doe's email address appears at the footer or whatever it needs to be so i would say you mock out all that data if it's already if you expect it to already be in the javascript in some javascript object just fill that before the test runs if in in like a setup method if you expect that test that data to be returned from an ajax call mock out the ajax call and just always return the data that you know will work for your test or that you know will fail your test so that you can test the failure cases anything else yeah is there a tool that i use to estimate how much time and effort it would take to write the test um a rule of thumb is uh my general rule of thumb is that for highly complex issues the tests are going to take longer to write than the code and for highly simplistic issues the tests are going to take longer to write than the code that's a terrible answer but unfortunately there isn't really a very good rule of thumb if you're trying if you're striving for 100 coverage then your test should take longer and uh and that's just that's the the nature of being a tdd environment that that's what it's going to be they should take longer solving those problems should be oh you know here's my code and here's a branch and here's a branch and creating all those branches isn't really that hard making sure that all those branches do exactly what you expect them to do is kind of tricky but what's nice is once you set up those tests for the initial development now you've got proper regression testing and so when you make a change to that you don't have to rewrite all the tests you're just writing a new test case for a bug you found or you're writing a test case for a new branch you created of your code or whatever it is so uh i would say that in terms of planning you need to plan for as much time as you're coding you should plan for creating tests regardless of whether you're doing tdd or not by the way if you're writing test afterward you're gonna need probably more time yeah do i find the need to write test code to test my test code i i i see what you're laying down there um i i i i generally ignore that that's not a good answer either but yeah there there are situations where you've got i mean we're writing JavaScript code so there are JavaScript functions and you can very easily have errors in your JavaScript functions what i find is most of the time my tests don't run when i have errors in that code and so it's not a problem what you really want to make sure you're doing is in your test blocks and those test functions that you're just calling a function and letting that function do what it's doing and returning they're like if you've got a parsing error that's one thing and you know your test won't run and then you know you've got a problem um if there's some something that you're doing some complex logic in there i would say abstract that concept that con complex logic to its own its own module its own function and then you can actually write a test for that complex functionality but you should if you have to do that you really need to look at why you're doing that and should that be part of your source code anything else yep uh yeah there's there's a ton of them i've used a number of them um js blanket is is one that we've used frequently we also use Istanbul i actually like the user interface of Istanbul a little bit more and we're using a mocha test mostly right now and mocha in Istanbul will play nice together so i would recommend those two but there's a you know a horde of other ones those are the ones that i've used and enjoy other questions yeah uh exactly like you saw we write the test case for that that search functionality right i have if you're properly abstracting your code uh such that your view interaction is is completely isolated i by the way i don't use backbone very often but we have the same issue with angular we have the same issue with knockout code that we write um where our views are separated and we've got to test just that and the way we do it is we have usually a partial that we load into our test case and we have uh our view code that's hitting the the uh that is we're passing in the elements that we want to target that we want to add event handlers to or whatever the case may be and then we are ensuring that those elements are properly positioned where we expect them that a modal does in fact show up and because you're running these tests in a browser even with phantom you can test that that element that pop-up element does exist that its visibility is is showing that it's not display none whatever the case may be but yeah we we we execute those tests just like we would anything else and just like we did our our search test here um again you have to make sure that your code is is accessible right you have to have testable javascript code even in your views you have to have code that you can access outside of the context of this is a view that's loaded through all of the other mechanism of backbone or knockout or angular or whatever anything else i think we've got we're right at time uh i have a horde of stickers up here feel free to come get one say hello hit me up on twitter these slides are there bit.ly slash testing hyphen js and please if you can go to bit.ly slash testing dash js dash review that's the review for this session i would really appreciate your feedback good or bad i appreciate any and all of it feel free to come up and punch me later if you didn't like it and i'll hang out around here and i'll be here uh all week so come up and say hello thank you for attending your first session


from theCUBE Studios in Palo Alto in Boston. It's theCUBE, covering IBM Think. Brought to you by IBM. Hi everybody, we're back and this is Dave Vellante. And you're watching theCUBE's coverage of the IBM Think 2020 digital event experience. Lisa Cisco is here. She's the global head of GoToMarket and IBM Cloud at Wipro. Lisa, good to see you. Thanks for coming on. How are you doing? Very good, thanks for having me. You're welcome. I'm holding up down in Florida. You guys staying safe? All good? Everyone staying safe, staying inside, working from home, like most of us. Everyone's doing good. So I want to ask you, I'm going to go right to it. Talk about digital transformation and I want to get your take and maybe share some thoughts that we've heard from clients. But digital transformation, you're kind of in the heart of it. You've got cloud, you're doing work with cognitive and AI and blockchain and the like. So what are you seeing in terms of how clients are adopting this notion, this digital transformation journey and how has COVID affected that? Great question. So hopefully the digital transformation won't always be about COVID, but there always will be a need for companies to move quickly and adopt new technologies and do things that are unexpected. Whether that's from an acquisition or an unexpected, competitive move or a new market that they want to be in. So any of those things can affect businesses. And what we're seeing right now is businesses who have adopted digital technology and by extension, adopted cloud as the backbone to that digital technology have been able to move faster in this environment. They're able to do things like work from home. They're able to ensure security is in place. They're able to give their employees and their customers access to information in a faster and more cost effective way. And so we're really not excited to have COVID but we're really, it's an interesting time to be looking at digital technologies and first mover advantages here. And the digital 2.0 era is all about enabling business responsiveness. And those are the things that we're doing with the technology plays that we're working on today. Yeah, I mean, the customers that we've talked to, the CIOs, the CISOs, they've said in many hard hit industries hey, we basically shut down spending with some exceptions, digital transformation being one of them. You've got experience in two areas that are being affected pretty dramatically by COVID. One is supply chain and the other is e-commerce.  So again, this was an area that if you had invested in your supply chain and you have automated some of those processes you're having an easier time onboarding your suppliers and knowing where your shipments are and understanding what your forward-looking position is going to be, if you haven't done those things even though your IT budgets might be being slashed there are things that you have to do right now and so doing some of those things using supply chain, automation, on the cloud it's the right way for companies to go right now that find themselves in a predicament and maybe aren't as prepared as they'd like to be so some of the technologies that we're helping bring to market we're seeing results with things like five times faster adoption and 40% more cost efficient than if they weren't trying to do these things in an automated way using the cloud and so for companies that need help doing this IBM has some of the best supply chain solutions in the market and Wipro certainly has years of experience bringing those to our clients. And then e-commerce is the other one I mean obviously there's been an explosion nobody wants to go out if they don't have to we're ordering anything and everything online and so there's been a kind of similar situation right if you had your kind of e-commerce if you've been running water through the pipes and you've perfected that over the last couple of years or part of a decade then you're in pretty good shape but so what are you seeing there with e-commerce? If you didn't have a loyal customer base now is the time to really get used to interacting with your customers in that way so restaurants for example think the local mom and pop shops I live in a small town outside of Orlando and I'm seeing little businesses get online and so clothing and wine and things that they wouldn't normally see and dabbling in e-commerce so it's really comfortable for most people now to buy things online and we're seeing services that you wouldn't normally be having online things like education K through 12 all colleges everything can be pretty much bought online these days or consumed in a digital format and so I think again customers that have experienced in doing this are ahead of the curve and customers that don't are going to quickly find that they have to. I want to turn our attention to in the conversation to cloud and get your perspectives I mean I've reported a number of times that the IBM cloud it's not an infrastructure as a service or the race to the bottom obviously IBM offers infrastructure service but IBM strategy is not to try to take AWS head on in storage costs per bit it's really to bring value through its software estate and portfolio and help its customers really take advantage of the cloud model. How are you and your clients taking advantage of the IBM cloud? What kind of solutions do you have that are specific that leverage the IBM cloud? That's correct we have two solutions that we're working on building out with IBM and leveraging hybrid cloud so for an environment where 94% of enterprises have multiple clouds now they all have a combination of AWS or Azure or private clouds or IBM cloud and 73% of our clients see the ability to move between those clouds as a high priority and we are addressing that with two main solutions that we've built out at Wipro one is called our boundary list enterprise solution and you can think of that as the infrastructure and the knowledge we've taken the knowledge from thousands of successful hybrid cloud migrations that we've done and we built it into this framework to help our customers be able to have a single dashboard and manage their view across hybrid cloud in an automated way and be able to be nimble and move between those clouds as business requirements demand that they do and so that's the boundary list enterprise side the other side that we're working on with IBM is the application and integration modernization we have a solution that we call modernizer and that is using some of the IBM technologies some third party technologies and again the Wipro knowledge from our successful engagements and making it so that we can easily see what the workload is gonna be to contain a rise and have a single integration methodology that we're going to be bringing to our clients to help them be able to do this in an automated in a better way, a faster way, a more economical way. So those are the two things that we're working on now some of IBM's products are under the covers things like multi cloud manager some of their DevOps and automation tools and there's some tools again from third parties and from Wipro that we've brought in there as well. So the boundary list enterprise I mean the idea there is that you've got a layer that allows you to go across clouds and have the same experience whether you're on-prem, whether you're in an Amazon cloud and IBM cloud, Azure, wherever, is that correct? And it's a single sort of cloud experience. Single dashboard, peanut glass so that you can look and you can serve in an IT environment your constituents the best way possible so that you're not locked into any cloud vendor and you can take advantage of where your workloads need to go. And the modernization piece, the modernizer talk about how clients are approaching that where do they start when they modernize their applicants that they do a kind of and you help them do an application portfolio assessment they identify the high value workloads in their portfolio maybe the ones that they're going to sunset is a rationalization exercise the first step maybe you could talk about that. Every client is different but if the client was to approach us and recommend the best practice we actually have a free two week consulting engagement that we use for our clients that take a look at the workloads that they have and potentially will want to move to cloud. We help them organize those workloads and figure out what the low hanging fruit will be the things that will take a little bit more time the things that are going to give them the highest bang for the buck and we will make some recommendations to them and that two week engagement about how to get started. What about the, I'm going to shift gears talk about what you guys done in India with the Novus lab what is that all about? What kind of expertise is there? How does, how do clients take advantage of that? So, Wipro and IBM had off the press soon to be announced we've just built it and we're soon to launch the IBM Wipro Novus Lounge Novus is the Latin word for new or for innovation and that's what we plan to be doing in this lounge together so we have Wipro talent, 150 seats where we'll have clients and different experts coming in and residing in that center as well as access to all of the products I just talked about we'll be working closely with the IBM GSI labs and bringing in new technologies building out new solutions so everything from taking supply chain to the next step to adding additional industry solutions one of the first things that we're going to do in that IBM Novus Lounge is take advantage of the new IBM financial services cloud which is going to be a covering cloud focused at that industry and we're really excited to get started working on that technology to bring it to our clients. So that's an example of an industry solution and it's what, it's optimized for banking and financial services, explain that if you would. That's correct, so IBM has worked with their clients in the financial services industry and they have packaged up some of the governance and security and regulations that are needed for the financial services industry and they've put that into a solution that they'll be rolling out shortly and I'm sure you'll hear more about it at IBM Think and that solution is going to be based on the industry guidelines by country rolling out in the US and then shortly to Europe and we're going to be able to use that to jumpstart a lot of the workloads that we want to bring to our financial services clients without having to make them reinvent the wheel for all of the governance and security and regulatory things that they need. Well I can see you guys doing this across multiple industries kind of an out-of-the-box, tune something for retail, government, financial services, manufacturing, healthcare where you've got the requisite of security and compliance edicts depending on where you are in the world, if it's a global organization you're able to identify what those local laws are, maybe there's certain analytics capabilities and dashboards that you'd include, is that kind of the right way to think about this? That's exactly where we're headed and we're already starting to talk about healthcare as the next industry we'll be tackling after financial services. Yeah well I mean healthcare is, they're so heads down right now, hopefully they come out of this and take a little breather and then can really get back to some of the more strategic things that they want to do in the industry. I'll leave you with the last word, kind of where you see the IBM Wipro partnership going, what's your vision for that? We really like IBM's approach in terms of avoiding vendor lock-in, we love what's happened with the acquisition of Red Hat and being able to use that technology more easily in our solutions. We think that the industry approach is the right approach, all of those things will have our focus in the Noon Dove's Lounge this year and so while things are unusual on this current environment and we have a lot of things that we have to do immediately to help our clients just be able to survive, we're very much looking to the future and what we can bring when this is all over that will help our clients make sure that they're ready for whatever the next response might be. Well Lisa, thanks very much for coming on theCUBE, we got a deep experience, I appreciate you sharing that with our audience. They saved. Thanks for having me. You're welcome and thank you for watching everybody. This is Dave Vellante for theCUBE and our continuing coverage, wall-to-wall coverage of IBM Think 2020, the digital event experience. You're watching theCUBE, we'll be right back right after this short break.


Oh my goodness look at this Hey, bolo buddies. Thanks for watching. All right, you guys in this video We are going to talk about plush in other words stuffed animals that sell for money on ebay and other platforms I'm going to tell you where they got it what they paid for it and what it sold for So I posted this in my bolo buddies facebook group and invited everyone in the group to share their best plush bolo So i'm going to share with you guys some big money stuffed animals of all things Can sell for big money Stuffed animal big money bolo. So let's get started here And you guys are welcome to go over to the facebook group and share your bolo And if you would like a shout out to your youtube channel or ebay store, just make sure you put that in the comments All right, so let's start here with the first one. It is a gans webkin signature bernice mountain dog realistic plush And no tag no code now. I will say sometimes having the code and the tag on the webkins can make themselves for more There's also another I think it is actually this one the signature brand. Let me show you the tag if they have it Yes, right here. See how it's gold a lot of times the signature brand can go for more not always I uh, I sold a dog. I want to say it was for over a hundred dollars and it was just a Dog that was not common and if I remember correctly I don't think there were any comps on it and I just priced it high and hoped for the best If you want to know more about webkins type bolo buddies webkins into the youtube search bar and it will pull up that video This one she said purchased at red racks for two dollars and eighty cents and sold for 39 99 overnight So, uh, she may have underpriced it. I'm not a hundred percent sure I didn't do any research on this One thing you can think about doing If you're not sure is starting the item on auction At the price you were going to price it at for buy it now So she could have started this at 39 99 And if the market demanded a higher price and multiple people wanted this it could have gone for more than the 40 dollars The next item here is mine. It's a rock and roll hall of fame bear stuffed animal It's got tattoos and piercings and a mohawk And I couldn't find another one like it and to be honest with you I've never seen one With these features So I went ahead and I believe I did an auction first and it did not sell And then I put it on buy it now with best offer And it sold for my sale price of 49 dollars and 60 cents and I picked this this up at the goodwill bins and The goodwill bins you buy buy weight And I do have videos where I shop at the goodwill bins if you guys want to see what that's like The next item kind of surprised me It's not a huge moneybolo, but it's kind of one of those that I think many of us would leave behind at the garage sale or the thrift store because it's aeropostal it is a clothing store stuffed animal and Probably not something I would think that would sell quickly or for good money But maybe somebody was looking for a penguin. I'm not really sure But it says my plush so far for this month bought off what not for a couple dollars sold for 25 But took a little bit to sell maybe four months not too bad Yeah, four months is not too bad in my opinion for plush plush can sit for a long time And not all of it is big money But uh, she did not say what she paid for but sold it for 25 dollars to me That's an unexpected plush bolo aeropostal guys No, well farm girl scavenger. No, well if you're not following her on youtube Definitely check her out. She is a wealth of knowledge and she sold a ton of furbies and she said And they keep selling This one went to aussie land and I already got great feedback. So australia. It looks like feel like shared A bunch of these in the last plush video Paid two dollars that in a state sale for 44 of these So two dollars each best resource for listing these is the furby wiki fandom page So if you want to learn about the value of the items and maybe additional information She's saying wiki fandom page. I've never heard of that She said do your research and Do not undersell even the broken ones will sell for more than 25 If you do the work Oh, even the broken ones will sell for more than 25 if you do the work so she's saying research them figure out what they sell for and Um really take the time to figure it out. This one works And she sold this for 82 49. You can see she put a video in the listing. I think that's very very smart Especially for electronics number one I think it offers you some protection if somebody opens a case against you I pretty sure ebay sides with the buyer and lets them return it no matter what but you at least have Something that you can say to the buyer. Hey, there's a video in my listing showing the item worked And that may be able to if it was damaged during transit help you with a claim or something like that Okay, so it looks like she sold it for 82 49 and paid two dollars for it She got a really good deal on those with the original box and everything This is a vintage resi prosal. Oh west germany wooden dolls Magdalena and friend vintage 1980s Not sure if these are really classified as plush, but i'm just going to leave that here Um, i'm going to say no not plush, but a really cool bolo and I like it So paid 50 cents each and lauded together also have some smaller ornament style ones listed Don't forget to follow me on youtube instagram whatnot and ebay farm girl scavenger newell And she's all yeah, she did put whatnot And you guys if you're not on whatnot definitely check it out It is a great place to score items to resell But it's also just a lot of fun to go and hang out So I hope to see you guys on a whatnot show. I am bolo buddies over there There is a referral link down below where you can get $15 to shop when you join with that link So I hope to see you guys. I do a lot of jewelry untanglings grabbing cell And it's super fun and even if you don't buy anything just come hang out. It's a great time It's kind of being like on youtube at a live show, but you're on whatnot the app all right vintage women's 70s ACme tan suede leather western tall cowboy boots I bought these women's boots for 10 at the salvation army and sold them for 199 on my posh mark The shoes were all picked over so I was bummed that day and picked the boots up because western always sells Little did I know how much they would sell for wow? 199 on those They almost look like yeah suede those are in really nice condition You guys know how suede gets when it gets wet and these look pretty good. I don't see any stains or anything The next item is this tonka mini pound puppy gg plus stuffed animal dog white poodle And she has a video. I'm not sure what it does, but She sold this Let's see. I sold a mini pound puppy For 20 dollars and 63 on ebay best offer. So that was all in with shipping I paid less than a dollar for it at a church sale and she has piece of scrap on youtube and ebay Now this is not a huge money bolo But it just goes to show you that you can pick plush up cheap and still flip it for a good profit So what she 10 times for money is that right? On a stuffed animal easy to list easy to ship I love selling plush and plush does really good on poshmark and mercari as well So if you are not cross posting definitely consider getting your plush on those other platforms This is a vintage vikma bamboo thumb sucking baby doll girl blonde blue eyes 1980s And it says it's a doll, but I thought it would fit here. This is an old doll I remember from childhood picked it up from an estate sale that gives me deals based on the box So I paid 15 for my box of choices. So less than two dollars a piece And it does have a plush body. It looks like Um, I was talking about cross posting. I do use list perfectly to cross post I do have videos tutorials that teach you how to use list perfectly You can get 30 off your first month when you use that Referral link down below. So definitely check out those videos See if it's a good fit for you. They just came out with the pro plan Pro plus plan recently and it's got a lot of new features So that may be something that you are more interested in now that they have Added features to list perfectly so super exciting updates And if you want to get on mercari and poshmark I do have referral links down in the description where you will get money to shop And when you use those links I get money to shop So thank you guys for checking out those referral and affiliate links down below. I appreciate it greatly Helps me keep this channel going and I just want to say thank you. So this next one is a vintage 1991 fisher price puff alarm plush pony zebra horse blue stars and stripes I have sold this one. I believe twice And always get excited when I find it because I know it's a bolo Picked up for a buck at a local thrift store and it looks like took a best offer of $55 on this one And so a dollar into 55 is fabulous and depending on the conditions. Sometimes they can go for more Star wars. Oh my goodness. Look at this I submitted these to the other post, but it's actually a plush bolo someone in a discord group sold theirs for like 400 And the day They sold the ones they had I looked and saw someone selling a lot of five of these plush for 90 from spain Bought them immediately and paid 120 all in to get them shipped to the states So I don't know if they bought it on ebay and then sold it on ebay I bet so these are an extremely rare plush sold at only a single star wars convention all remaining plush were destroyed after the convention because IP lawyers feared a lawsuit from ugly dolls Due to the similarities. Oh my goodness A lawsuit probably would have complicated the deal disney made to buy star wars 22 months later These took three months to sell and accepted a best offer of 450 Wow That is interesting. What do you guys think about that?  So be on the lookout for the ones that have these kind of faces Looks like they're valuable. They're probably do pretty good on their own as well individually Okay, this one all right. This is not a plush. It was put in the wrong location, but that's okay I'm still going to share it and it is a I always forget how to say these dog rario type I know that's totally wrong, but it is a type of photo and It's a lady who died of Is it chloria? Oh my goodness you guys that's horrible that I don't know how to say that The same year the photo was taken purchased for 13 and sold for 200 the same day So I have no idea how he knows this information about her Oh, look she was from Ohio Wow Check that out And their store is antique photo stock So if you want to learn more or see more check that out But it looks like they were able to research the woman maybe by the name on the back Wow That is interesting. What do you guys think about that? Besides, I can't pronounce things All right, not a plush, but definitely something intriguing All right, the next one says my ebay store is leo's treasures I purchased this 2005 pinhurst us open golf tournament teddy bear souvenir at a local garage sale for two dollars It's sold when my plush was on sale for 15 off and it sold for 32 94 in the buyer paid shipping So just a little cutie here And it has to do with a tournament. So Maybe a little more long tail looking for a specific buyer Or it sells fast because somebody has maybe it in their search history as things to alert them for All right, let's look at the next one hallmark disney baby Minnie Mouse face Bo lovey security blanket blanky This is also from leo's treasures I purchased this hallmark disney baby Minnie Mouse plush lovey at a garage sale for a dollar It was new with tags. It sold for full asking price of 32 75 and the buyer paid shipping So it's flat how cute is that? It's adorable. She did a great job with her photos guys. See how she's got close-ups of the condition. She's got the measurement There you go And the next one is a vintage 1990 applause boo boo elephant 16 inch stuffed plush with tag And she said I purchased this vintage 1990 applause boo boo elephant Stuffed the animal with the tags at the goodwill for two dollars and 99 cents when I bought it I thought it would sell quickly, but it sat for a long time So I unlisted and sold similar and it sold almost immediately It sold for full asking price of 49 75 and the buyer paid shipping So let me know what you guys think about that Have you ever thought something was going to sell quickly and it didn't and Then you relisted it and it sold fast I know that I I think all of us should maybe after so long. I don't know if I recommend doing it monthly I don't really have a recommendation honestly. You guys Put your feedback on what you do and if you think it's helpful. I know a lot of people do it monthly I don't have time to do it monthly, but People say that it will bump it in the algorithm when you Relist and sell similar or end your item and sell similar So let me know she says it worked for her But it is it is time All right, here we go Rare vintage. Hello kitty plush stuffed knock a jima Sanrio tan hawaiian Winking bikini now the bikini is not winking It was one of the plushies my daughter didn't want anymore. It was a christmas gift from a family member years ago So it was free. So in another video. I talked about things sitting in your house So she took something that was her daughter's and flipped it for a nice profit of 74 99 So has anybody Actually started listing things from their house. Let me know in the comments I know quite a few of you commented that oh, I need to do this. This is a good idea. Um Let me know if you had any success with that Did you find any bolo's because this bolo was sitting in probably her daughter's room All right. Hello kitty is definitely a bolo. Also. Hello kitty does very well on mercari If you want to see plush comparisons of items that sold on mercari versus eBay check out my build a bear video. Oh my goodness. It's unbelievable unbelievable Vintage 1977 bradley's department store brough Play safer bear stuffed stuffed plush hasbro Look at this old guy. He even has a little defect right here I found this 1977 vintage plush for $2.99 at the Goodwill He had a few rips on the seams of his shirt and fur was a little bit matted Based on research listed high at 125 ran a sale and accepted an offer of 89 My I'm sorry. eBay store is no flipping way. Thanks Courtney for all you do. Oh, thank you so much for sharing That is a good one. Okay. This one's mine. This was just another unexpected This little guy is only five inches tall And I got him at the Goodwill Bend so probably less than a buck I couldn't find any comps on it. I did not check worth point because I I don't think I did I probably should have But I didn't so what I did is a lot of times I will run an auction first just to make sure that You know, it's not a big money bolo that people are going to fight over A lot of times when you have a plush or any item that is harder to find There are people that are waiting for that item to post. So I went ahead. I believe I did an auction Maybe once or twice. That's typically what I do on items. I can't find and it didn't sell So I relisted it and put it on sale and it sold for my sale price of $49 and 60 cents So less than a dollar investment at the Goodwill Bend's and flipped it pretty quickly for the 49 60 And it's just a little guy and it's scholastic So this is probably something that came with a book at a book fair or something like that I think scholastic is books, right Anyway, uh, definitely be on the lookout for the unexpected another item that I sold that was kind of unexpected was a bob evans plush it was just a inexpensive little bob evans plush, but somebody was looking for it and I priced it high and it sold so Uh, yeah, you just never know with plush. You got to look it up. You got to look it up I just did another video, uh, where somebody had shared their best March Bolo in the facebook group and it was a Unexpected brand just a cheap brand and the item I believe it sold for over a hundred dollars So watch for that video. I'm not sure which one will post first, but oh my goodness. I was shocked Completely shocked at what it sold for because it was not something that I thought would go for big money not that brand Nope, I know the item goes for big money, but not that brand. All right, you guys if you want to share your best plush bolo Um, I have a new share post up in the facebook group. I always pin those to the top You can check that out share plush And make sure you shout out your youtube channel or your social media selling platform Whether that's ebay or whatnot or wherever you sell put that in the comment So I can read it and you guys can get a shout out and again best Plush for april is up. All right. Let me know what you think about those big money plush. Thank you so much for being here Thank you for watching. Be sure to like comment subscribe and share and thanks for watching