WEBVTT 00:00:17.940 --> 00:00:19.620 NEAL KEMP: Hi RailsConf. 00:00:19.620 --> 00:00:21.190 Today we're going to be talking about 00:00:21.190 --> 00:00:23.220 testing your services. 00:00:23.220 --> 00:00:24.330 But before we get into that, 00:00:24.330 --> 00:00:26.490 I want to introduce myself. 00:00:26.490 --> 00:00:29.200 My name's Neal. I'm originally from Iowa, 00:00:29.200 --> 00:00:32.320 so I feel at home here in the Midwest. 00:00:32.320 --> 00:00:35.380 Now I live in California, in LA specifically, 00:00:35.380 --> 00:00:36.870 and I'm a software developer and 00:00:36.870 --> 00:00:39.690 independent consultant who does Rails, 00:00:39.690 --> 00:00:42.050 JavaScript, HTML, CSS. 00:00:42.050 --> 00:00:43.340 Basically if you name an acronym 00:00:43.340 --> 00:00:46.129 I've probably coded in it at some point. 00:00:46.129 --> 00:00:49.710 So, today's talk is going to be the what, 00:00:49.710 --> 00:00:54.790 the why, and the how of testing your services. 00:00:54.790 --> 00:00:57.879 This is not a talk about building testable services. 00:00:57.879 --> 00:00:59.980 I could do an entire talk about that on 00:00:59.980 --> 00:01:04.290 its own. It's also not necessarily a talk about 00:01:04.290 --> 00:01:08.190 test-driven development. While I'm a practitioner, I don't think 00:01:08.190 --> 00:01:12.750 that the principles applied here correspond directly to test-driven 00:01:12.750 --> 00:01:14.800 or not test-driven development. 00:01:14.800 --> 00:01:15.940 [laughter] 00:01:15.940 --> 00:01:21.640 So. Got that one. Good. 00:01:21.640 --> 00:01:24.000 So first we're gonna talk about the what. So, 00:01:24.000 --> 00:01:26.280 we have to ask ourselves, what is a service. 00:01:26.280 --> 00:01:29.320 So I break it down into two main categories. 00:01:29.320 --> 00:01:31.760 First of all we have external services, like the 00:01:31.760 --> 00:01:37.550 Twitter API, Facebook's API, or Amazon Web Services. And 00:01:37.550 --> 00:01:41.810 the other category is internal software-oriented architecture, a buzz 00:01:41.810 --> 00:01:44.380 word we all know and love. 00:01:44.380 --> 00:01:47.940 So, basically for the purpose of this talk, it 00:01:47.940 --> 00:01:52.670 means anytime you're making an HTTP request to an 00:01:52.670 --> 00:01:57.410 endpoint in another repository. So, basically any network request 00:01:57.410 --> 00:02:01.250 you're making outside of your application. 00:02:01.250 --> 00:02:04.120 So now we're gonna talk about. Cause we need 00:02:04.120 --> 00:02:07.110 some justification before we go ahead and test all 00:02:07.110 --> 00:02:11.129 of our services without question. So, first we have 00:02:11.129 --> 00:02:13.530 to ask ourselves, why are services themselves important? I 00:02:13.530 --> 00:02:15.970 think a lot of these are pretty self-evident. It 00:02:15.970 --> 00:02:18.700 allows us to build things faster. It allows us 00:02:18.700 --> 00:02:22.050 to scale more easily. And we use them on 00:02:22.050 --> 00:02:25.330 basically every application. I don't think I can personally 00:02:25.330 --> 00:02:27.750 think of an app I've built in the past 00:02:27.750 --> 00:02:31.300 few years that hasn't glued on multiple services. 00:02:31.300 --> 00:02:33.410 And I'm also noticing that we're using more and 00:02:33.410 --> 00:02:38.030 more services for every application. So I would argue 00:02:38.030 --> 00:02:42.490 that services are critical to modern Rails development. So 00:02:42.490 --> 00:02:44.490 we have to ask ourselves then, why is testing 00:02:44.490 --> 00:02:47.800 those services important? Well, first of all, you should 00:02:47.800 --> 00:02:50.230 be testing everything else, so why would it be 00:02:50.230 --> 00:02:54.819 different for services? And services often compose critical features 00:02:54.819 --> 00:02:58.590 of your application. For example, a stripe integration. If 00:02:58.590 --> 00:03:00.200 your billing's down, you're gonna have a lot of 00:03:00.200 --> 00:03:04.400 issues. You know, if you have an API request 00:03:04.400 --> 00:03:06.550 to S3, you're not gonna be able to serve 00:03:06.550 --> 00:03:08.800 images, if that's down. 00:03:08.800 --> 00:03:11.230 And you might also encounter problems with these APIs. 00:03:11.230 --> 00:03:14.900 I know I sure have. Basically, any time I've 00:03:14.900 --> 00:03:18.550 worked with an API there's been some unexpected results. 00:03:18.550 --> 00:03:20.690 So the first example I'm gonna take you through 00:03:20.690 --> 00:03:24.480 is, you know, an internal API built by consultants 00:03:24.480 --> 00:03:26.180 in another part of the company. So this is 00:03:26.180 --> 00:03:30.500 the software-oriented architecture we're talking about. And they were 00:03:30.500 --> 00:03:33.819 exposing this API for our Rails app to consume, 00:03:33.819 --> 00:03:36.810 but we had issues all along the way, and 00:03:36.810 --> 00:03:41.250 it served to increase the project length significantly. Sometimes 00:03:41.250 --> 00:03:43.860 we'd have random null responses when we were supposed 00:03:43.860 --> 00:03:47.610 to get objects. There is random inconsistencies where we'd 00:03:47.610 --> 00:03:52.230 get weird symbols being printed out and different formatting. 00:03:52.230 --> 00:03:54.770 And in general it was a catastrophe. 00:03:54.770 --> 00:03:57.840 So it definitely lengthened the time to completion. And 00:03:57.840 --> 00:04:00.569 this was a lot due to a failure on 00:04:00.569 --> 00:04:03.560 our part to, you know, test the API thoroughly. 00:04:03.560 --> 00:04:05.980 So we couldn't express to them, you know, the 00:04:05.980 --> 00:04:07.560 problems we were having until we put it into 00:04:07.560 --> 00:04:10.300 production. So this is one problem that could have 00:04:10.300 --> 00:04:12.890 been solved by testing first. 00:04:12.890 --> 00:04:15.959 So, now we're gonna talk about a few problems 00:04:15.959 --> 00:04:18.269 I've had with external APIs. And I'm sure all 00:04:18.269 --> 00:04:21.899 of you have encountered similar issues with APIs in 00:04:21.899 --> 00:04:22.539 the past. 00:04:22.539 --> 00:04:25.539 So do we have any NHL fans in the, 00:04:25.539 --> 00:04:28.090 in the house here? Yeah? Chicago Black Hawks. Doing 00:04:28.090 --> 00:04:30.810 pretty well in the play-offs so far. We'll see 00:04:30.810 --> 00:04:32.990 how they go. I mean, obviously they're gonna get 00:04:32.990 --> 00:04:35.669 crushed by the Kings in a few rounds here, 00:04:35.669 --> 00:04:38.820 or the Sharks, possibly. But we'll see. I don't 00:04:38.820 --> 00:04:41.270 want to start a sports rivalry today. 00:04:41.270 --> 00:04:45.830 So you know, this basically ranged from small annoyances 00:04:45.830 --> 00:04:49.710 to, you know, major issues with this API. So 00:04:49.710 --> 00:04:52.620 we'd have annoyances like this, where some responses would 00:04:52.620 --> 00:04:55.370 come back with an id for the team, and 00:04:55.370 --> 00:04:57.180 others would come back with a code. And in 00:04:57.180 --> 00:04:59.550 this case, both of them refer to Anaheim. So 00:04:59.550 --> 00:05:01.490 this is a minor annoyance. You can code around 00:05:01.490 --> 00:05:02.050 that. 00:05:02.050 --> 00:05:06.139 Here, we have an undocumented bug, where basically the 00:05:06.139 --> 00:05:07.870 goals were all supposed to be as a part 00:05:07.870 --> 00:05:09.630 of an array, but if you only had one 00:05:09.630 --> 00:05:11.860 goal, it would be an object. And sadly we 00:05:11.860 --> 00:05:16.389 discovered this one in production, during a game. So 00:05:16.389 --> 00:05:18.060 that wasn't ideal. 00:05:18.060 --> 00:05:21.270 But, worst of all, after we had gone through 00:05:21.270 --> 00:05:24.270 all of the trouble of fixing these, we realized 00:05:24.270 --> 00:05:26.889 that there was no versioning on this API. So, 00:05:26.889 --> 00:05:30.250 even if we fixed it, we might be fixing 00:05:30.250 --> 00:05:35.240 it again a week later. So this is basically 00:05:35.240 --> 00:05:38.710 what it felt like to work with their API. 00:05:38.710 --> 00:05:41.740 So, another project I worked on, this is just 00:05:41.740 --> 00:05:44.389 kind of a fun side project, was a Snapchat 00:05:44.389 --> 00:05:47.580 API Client, so I could, you know, work with 00:05:47.580 --> 00:05:51.620 the Snapchat private API. And, well, one of these 00:05:51.620 --> 00:05:55.810 examples is extreme, in that there is haphazard documentation, 00:05:55.810 --> 00:05:59.240 or no documentation, in this case. I think we've 00:05:59.240 --> 00:06:03.919 all worked with APIs that have improper documentation. 00:06:03.919 --> 00:06:05.250 But in this case we didn't even know what 00:06:05.250 --> 00:06:07.240 the requests were, so we had to figure that 00:06:07.240 --> 00:06:11.240 out. There's also bizarre obfuscation implanted inside of the 00:06:11.240 --> 00:06:15.699 app itself that basically encrypted, on their iPhone, so 00:06:15.699 --> 00:06:19.009 people like me couldn't go in and build things 00:06:19.009 --> 00:06:21.169 like this. And there's a GitHub link if you're 00:06:21.169 --> 00:06:22.280 curious. 00:06:22.280 --> 00:06:25.530 So, now that we've talked a little bit about 00:06:25.530 --> 00:06:28.729 why it's important and outlined some of the problems 00:06:28.729 --> 00:06:31.290 you might encounter, we're gonna talk about how you're 00:06:31.290 --> 00:06:36.180 actually going to test these. 00:06:36.180 --> 00:06:38.240 So first we need to ask ourselves, what is 00:06:38.240 --> 00:06:43.100 different about services than regular code that we're testing? 00:06:43.100 --> 00:06:47.150 Well, first of all, we have external network requests 00:06:47.150 --> 00:06:49.800 that are being made, and second of all, you 00:06:49.800 --> 00:06:51.860 don't own the code, so you can't really do 00:06:51.860 --> 00:06:54.050 unit testing on it. It all has to be 00:06:54.050 --> 00:06:56.930 done from integration test perspective. 00:06:56.930 --> 00:07:01.930 So, what I propose for your tests, in general, 00:07:01.930 --> 00:07:05.820 is that you turn Airplane Mode on. This, I 00:07:05.820 --> 00:07:08.240 find, is the best way to think about your 00:07:08.240 --> 00:07:11.509 tests, because, first of all, failure is really bad 00:07:11.509 --> 00:07:14.680 in testing, and you shouldn't be making any, any 00:07:14.680 --> 00:07:16.820 network requests. 00:07:16.820 --> 00:07:18.770 So I think of this kind of in two 00:07:18.770 --> 00:07:20.889 ways. First of all, so it's Airplane Mode in 00:07:20.889 --> 00:07:23.300 the test mode so you can't do these things. 00:07:23.300 --> 00:07:24.960 But also it should be a test that you 00:07:24.960 --> 00:07:28.360 can run on an airplane. Basically meaning that if 00:07:28.360 --> 00:07:31.110 you're, you know, on a long trans-Atlantic flight or 00:07:31.110 --> 00:07:33.360 in the RailsConf lobby, you can still make your 00:07:33.360 --> 00:07:39.600 tests and, and they won't fail because of network 00:07:39.600 --> 00:07:42.180 issues. 00:07:42.180 --> 00:07:44.930 So this means you should not interact with your 00:07:44.930 --> 00:07:48.880 services from your testing environment. And we have a 00:07:48.880 --> 00:07:52.830 few caveats which I'll get into now. So, this 00:07:52.830 --> 00:07:56.770 includes dummy APIs. So there's some API makers that 00:07:56.770 --> 00:07:59.289 have their real API, and then they have a 00:07:59.289 --> 00:08:02.580 fake API which you can hit with requests, but 00:08:02.580 --> 00:08:05.729 it doesn't make any changes to your data. 00:08:05.729 --> 00:08:07.930 So you can't hit those, because those are somewhere 00:08:07.930 --> 00:08:11.199 else on the network. But I do allow you 00:08:11.199 --> 00:08:16.220 to make pre-recorded responses to those end points, and 00:08:16.220 --> 00:08:18.130 that means you can record them within your test 00:08:18.130 --> 00:08:19.919 suite, which we'll get into in a bit more 00:08:19.919 --> 00:08:21.530 detail later. 00:08:21.530 --> 00:08:25.300 So, for these examples, I'm going to be assuming 00:08:25.300 --> 00:08:29.479 that you're using Rails, obviously, and that you're using 00:08:29.479 --> 00:08:35.259 rspec for simplicities sake. So, it's time to stub 00:08:35.259 --> 00:08:36.919 out these requests. 00:08:36.919 --> 00:08:40.809 So, when you're stubbing an object, you're basically - 00:08:40.809 --> 00:08:43.039 for those who don't know - it's basically putting 00:08:43.039 --> 00:08:45.310 like a fake object in front of that object, 00:08:45.310 --> 00:08:47.880 so you're hitting that object instead of hitting the 00:08:47.880 --> 00:08:50.270 real one and, you know, saving time with, like 00:08:50.270 --> 00:08:53.790 setup processes and stuff like that. And we're doing 00:08:53.790 --> 00:08:56.370 a similar thing when you're stubbing a request to 00:08:56.370 --> 00:08:59.110 an endpoint, except we're saving a lot more time 00:08:59.110 --> 00:09:00.870 when we're doing so, because we don't have to 00:09:00.870 --> 00:09:04.490 make that additional network request. 00:09:04.490 --> 00:09:07.990 So there's some libraries that include built-in stubbing. So 00:09:07.990 --> 00:09:12.580 Typhoeus, if I pronounced that correctly, Faraday and Excon 00:09:12.580 --> 00:09:17.680 are three examples of pretty widely-used HTTP libraries built 00:09:17.680 --> 00:09:21.350 on top of net HTTP, I think, that have 00:09:21.350 --> 00:09:24.089 built-in stubbing functionality. 00:09:24.089 --> 00:09:26.690 But we can simplify this a little bit and 00:09:26.690 --> 00:09:29.399 use something called webmock, which I'm sure many of 00:09:29.399 --> 00:09:32.010 you have worked with in the past, which is 00:09:32.010 --> 00:09:35.880 a general purpose stubbing library for your test suite, 00:09:35.880 --> 00:09:39.870 so you don't have to learn each individual library's 00:09:39.870 --> 00:09:42.750 stubbing methods. 00:09:42.750 --> 00:09:44.600 So I'll take you through a quick example. Here 00:09:44.600 --> 00:09:48.870 is basic spec_helper. Nothing really interesting about this, except 00:09:48.870 --> 00:09:52.440 you have to include disable_net_connect! at the bottom. The 00:09:52.440 --> 00:09:57.110 rest is boilerplate. So I've highlighted that. And, obviously, 00:09:57.110 --> 00:09:58.880 with all of these examples, you should be putting 00:09:58.880 --> 00:10:02.180 the gem in your gem file and bundle installing 00:10:02.180 --> 00:10:04.310 before you start. 00:10:04.310 --> 00:10:06.930 So, when you put this in your code for 00:10:06.930 --> 00:10:09.510 the first time, you'll get a really great error 00:10:09.510 --> 00:10:11.620 with this, and I really like getting these errors, 00:10:11.620 --> 00:10:14.370 because it tells me exactly, in my code, where 00:10:14.370 --> 00:10:16.850 I'm making network requests. So if you're not already 00:10:16.850 --> 00:10:22.290 doing airplane mode tests, you should just plug this 00:10:22.290 --> 00:10:25.620 disable_net_connect! in, and then you'll get this error, which 00:10:25.620 --> 00:10:28.830 will tell you where you're making these network requests. 00:10:28.830 --> 00:10:31.220 And it also is really handy, and it gives 00:10:31.220 --> 00:10:33.810 you, actually, the request you're making at the bottom. 00:10:33.810 --> 00:10:37.680 So you can copy and paste that into your 00:10:37.680 --> 00:10:40.640 test in order to stub it automatically. And obviously 00:10:40.640 --> 00:10:42.880 you'll have to collect the body and the headers 00:10:42.880 --> 00:10:47.080 yourself, if you need to use those as well. 00:10:47.080 --> 00:10:51.570 So, for the following examples, we're gonna use probably 00:10:51.570 --> 00:10:57.670 the most, sorry, most simple FacebookWrapper ever invented. Basically, 00:10:57.670 --> 00:11:01.490 all we're doing here is sending a GET request 00:11:01.490 --> 00:11:06.269 to Facebook graph, the public API, for a user. 00:11:06.269 --> 00:11:08.029 And what this does is it just returns, like, 00:11:08.029 --> 00:11:11.260 very basic Facebook information about you. It has your 00:11:11.260 --> 00:11:15.050 Facebook username, your name, and an id and a 00:11:15.050 --> 00:11:17.010 few other fields. 00:11:17.010 --> 00:11:18.990 And then what we're doing with user_id up at 00:11:18.990 --> 00:11:22.740 the top is we are just pulling out the 00:11:22.740 --> 00:11:26.980 value for key_id. So this, all it does is 00:11:26.980 --> 00:11:33.060 return your Facebook id. Super, super simple. And make 00:11:33.060 --> 00:11:34.959 sure, since we're putting it in lib, that you 00:11:34.959 --> 00:11:38.279 require it at some point in your loading. 00:11:38.279 --> 00:11:40.930 So now we're gonna look at a test for 00:11:40.930 --> 00:11:43.130 this. So this is a test where we're not 00:11:43.130 --> 00:11:45.440 making a network request, but we're stubbing it out 00:11:45.440 --> 00:11:49.310 with webmock. So, at the bottom, you can see 00:11:49.310 --> 00:11:53.390 we're doing our testing case, and we're setting up 00:11:53.390 --> 00:11:57.769 an expectation that our user_id is equal to Arjun's 00:11:57.769 --> 00:12:00.890 user_id. And I'm using Arjun because he was the 00:12:00.890 --> 00:12:03.560 maker of the Facebook graph API wrapper. 00:12:03.560 --> 00:12:07.080 And, you can see, now, above, we are stubbing 00:12:07.080 --> 00:12:10.130 the request, just like you'd stub an object. We're 00:12:10.130 --> 00:12:13.380 stubbing the method of the HTTP request and then 00:12:13.380 --> 00:12:18.329 we're send, putting the link as the second argument. 00:12:18.329 --> 00:12:23.230 Next, we have to set up what it returns, 00:12:23.230 --> 00:12:26.700 and this is just an HTTP response that we're 00:12:26.700 --> 00:12:28.990 returning. So we want to put a status. 00:12:28.990 --> 00:12:32.560 You can set headers, which I generally don't do, 00:12:32.560 --> 00:12:35.420 but if you're doing any operations with the headers, 00:12:35.420 --> 00:12:40.670 you should definitely set up these in your responses. 00:12:40.670 --> 00:12:43.640 And the body, we have a really simple JSON 00:12:43.640 --> 00:12:46.670 string. I've cut out a few fields for brevity. 00:12:46.670 --> 00:12:49.170 But you can see it has an id, a 00:12:49.170 --> 00:12:51.380 first_name, and a username. 00:12:51.380 --> 00:12:54.649 So, this test will pass, and we're also making 00:12:54.649 --> 00:12:58.200 no net requests, work requests. So, the reasons it's 00:12:58.200 --> 00:13:01.730 better is it, first of all, it's faster, and 00:13:01.730 --> 00:13:04.019 we also aren't getting this intermittent failure that we 00:13:04.019 --> 00:13:09.110 were talking about earlier from the network request. 00:13:09.110 --> 00:13:12.920 So, that's a good general way, but there's ways 00:13:12.920 --> 00:13:15.200 we can also save time with this. So a 00:13:15.200 --> 00:13:19.459 lot of the really popular libraries for API wrappers 00:13:19.459 --> 00:13:24.220 also include mock-services within themselves or as an additional 00:13:24.220 --> 00:13:26.860 library on the side, and they use that for, 00:13:26.860 --> 00:13:29.649 you know, internal testing with their gems. So I 00:13:29.649 --> 00:13:32.450 recommend, if, if you can find one, to use 00:13:32.450 --> 00:13:34.860 this before you can go and use webmock, because 00:13:34.860 --> 00:13:36.040 it'll save you a lot of time. 00:13:36.040 --> 00:13:38.810 And I'll take you through a quick example. So 00:13:38.810 --> 00:13:44.959 we're gonna use Facebook graph mock here. And all 00:13:44.959 --> 00:13:48.370 we are doing is putting it into spec_helper. We're 00:13:48.370 --> 00:13:53.089 just including the methods and requiring it. Pretty straightforward. 00:13:53.089 --> 00:13:56.120 And now we're gonna look at a spec. 00:13:56.120 --> 00:14:00.670 So, basically, all we're doing is we're wrapping the 00:14:00.670 --> 00:14:05.190 test case within a wrapper that mocks out the 00:14:05.190 --> 00:14:07.829 request. So basically, all this one's doing is saying 00:14:07.829 --> 00:14:11.450 we're sending a git request to Facebook graph back 00:14:11.450 --> 00:14:14.519 slash Arjun, and then the third argument, in this 00:14:14.519 --> 00:14:20.190 case, is users/arjun_public, which is where the JSON file 00:14:20.190 --> 00:14:22.959 of this response is located in the gem. 00:14:22.959 --> 00:14:26.910 So, you can also specify your own responses, and 00:14:26.910 --> 00:14:29.850 I'd recommend you do that, because I found, actually, 00:14:29.850 --> 00:14:34.410 some issues with the Facebook graph mock mocking, like, 00:14:34.410 --> 00:14:38.670 responses, have some outdatedness in them. 00:14:38.670 --> 00:14:41.959 So, but this, you know, example, I'm not gonna 00:14:41.959 --> 00:14:43.610 take you through all of the gems that have 00:14:43.610 --> 00:14:46.290 this. But this can go to show that there 00:14:46.290 --> 00:14:49.730 are some benefits that you get from using this. 00:14:49.730 --> 00:14:51.600 It's already stubbed for you. You don't have to 00:14:51.600 --> 00:14:55.709 learn the API endpoints in order to use it, 00:14:55.709 --> 00:14:59.010 and some of these provide prerecorded responses for your 00:14:59.010 --> 00:15:01.149 use, so you don't have to go out and 00:15:01.149 --> 00:15:03.200 collect these. So it's just a good way of 00:15:03.200 --> 00:15:06.850 saving time, if you're using some popular libraries. 00:15:06.850 --> 00:15:10.779 Next, I'm going to take you through sham_rack, which 00:15:10.779 --> 00:15:14.000 is one of my more favorite ways of doing 00:15:14.000 --> 00:15:15.870 this. I kind of find this to be a 00:15:15.870 --> 00:15:20.490 fun way. Basically what sham_rock does, sorry, sham_rack does 00:15:20.490 --> 00:15:24.320 is it allows you to mount rack-based apps, which 00:15:24.320 --> 00:15:28.290 include Rails and Sinatra and others, and it allows 00:15:28.290 --> 00:15:33.519 you to make requests against these fake apps. 00:15:33.519 --> 00:15:36.510 So, in this case, we're going to get a 00:15:36.510 --> 00:15:39.769 little help from Sinatra in order to stub out 00:15:39.769 --> 00:15:45.550 these endpoints. So, spec_helper, the only thing interesting is 00:15:45.550 --> 00:15:50.360 that we leave in web-mock. Pretty boring there. But 00:15:50.360 --> 00:15:52.949 then we get to our fake. So I usually 00:15:52.949 --> 00:15:56.649 just put this spec/support and then fake whatever it 00:15:56.649 --> 00:15:59.089 is, in this case fake_facebook. 00:15:59.089 --> 00:16:01.370 And this just means it'll be loaded when you 00:16:01.370 --> 00:16:05.800 run your specs automatically. But it won't be, obviously, 00:16:05.800 --> 00:16:09.399 loaded into your production or staging environments, or development. 00:16:09.399 --> 00:16:12.000 So, in this case, at the top we can 00:16:12.000 --> 00:16:15.110 see, we're calling sham_rack, and we're setting up the 00:16:15.110 --> 00:16:17.139 endpoint which we're hitting against, which in this case 00:16:17.139 --> 00:16:20.380 is graph dot facebook dot com. And 433 is 00:16:20.380 --> 00:16:25.100 just specifying that we're using the HTTPS SSL link, 00:16:25.100 --> 00:16:27.010 and dot Sinatra just means we're going to be 00:16:27.010 --> 00:16:29.610 passing it in a Sinatra app. 00:16:29.610 --> 00:16:33.829 So, basically, contained within this block is a Sinatra 00:16:33.829 --> 00:16:35.990 app, and you can do virtually anything you can 00:16:35.990 --> 00:16:37.820 do with a regular Sinatra app, which is really 00:16:37.820 --> 00:16:41.010 cool. So you can just, you're just basically mounting 00:16:41.010 --> 00:16:43.920 this and testing against it. 00:16:43.920 --> 00:16:47.019 So, for those of you who don't use Sinatra 00:16:47.019 --> 00:16:50.610 very much, all we're doing here is specifying with 00:16:50.610 --> 00:16:53.630 the GET keyword that we're making a GET request 00:16:53.630 --> 00:16:57.519 to back slash something, and just like Rails, when 00:16:57.519 --> 00:17:00.889 you rake routes you'll see the parametrization of things 00:17:00.889 --> 00:17:02.680 with a colon before it. We're doing the exact 00:17:02.680 --> 00:17:04.959 same thing here with username. 00:17:04.959 --> 00:17:07.898 So, you'll see, in the middle, in the link 00:17:07.898 --> 00:17:10.740 we interpolate params username, and that's how you pull 00:17:10.740 --> 00:17:14.169 that out. So this is essentially just returning a 00:17:14.169 --> 00:17:17.919 string that is this response. You can obviously spice 00:17:17.919 --> 00:17:21.369 this up by setting status codes, adding conditionals in 00:17:21.369 --> 00:17:24.939 here if you need some more dynamic power, and 00:17:24.939 --> 00:17:28.580 also setting up the headers. And you can also, 00:17:28.580 --> 00:17:31.330 which I sometimes do this in my testing, is 00:17:31.330 --> 00:17:33.559 back it with like a small yml database, so 00:17:33.559 --> 00:17:36.309 you can get some more realistic data than just 00:17:36.309 --> 00:17:39.509 a simple string. 00:17:39.509 --> 00:17:46.470 So, that's the response. And. Now, when we're writing 00:17:46.470 --> 00:17:52.169 our spec for sham_rack, all we're doing is keeping 00:17:52.169 --> 00:17:53.779 it on this base level. We don't have to 00:17:53.779 --> 00:17:56.739 wrap it with anything, because it will automatically, in 00:17:56.739 --> 00:17:59.700 your tests, pick up the fact that you have 00:17:59.700 --> 00:18:02.710 sham_rack mounted, and it will automatically hit against that 00:18:02.710 --> 00:18:08.179 endpoint rather than hitting against the network. 00:18:08.179 --> 00:18:12.759 So, you might ask, why is this better? I 00:18:12.759 --> 00:18:14.879 think there are a few reasons. First, I find 00:18:14.879 --> 00:18:18.100 it more dynamic. I find it more expressive as 00:18:18.100 --> 00:18:20.429 well, and you can really add, you know, as 00:18:20.429 --> 00:18:24.179 much functionality you need to test your integrations as 00:18:24.179 --> 00:18:25.769 you want. And you can also back it with 00:18:25.769 --> 00:18:28.970 yml if you need, you know, some pre-population of, 00:18:28.970 --> 00:18:32.529 you know, real data. And it's also more readable. 00:18:32.529 --> 00:18:34.759 Let's go back to this for a second. And, 00:18:34.759 --> 00:18:37.479 you can see, like, reading through this is a 00:18:37.479 --> 00:18:39.340 lot easier to parse through, and you know where 00:18:39.340 --> 00:18:41.859 the API requests are being made to, versus the 00:18:41.859 --> 00:18:44.830 stubbing we showed in the first example, with web-mock, 00:18:44.830 --> 00:18:46.269 is a little bit hard to read. So that's 00:18:46.269 --> 00:18:48.859 why I prefer to use this. 00:18:48.859 --> 00:18:52.950 So next, we're going to talk about vcr, which 00:18:52.950 --> 00:18:55.299 is a pretty widely-used gem. And this one has 00:18:55.299 --> 00:18:58.379 some other benefits that I think are really important 00:18:58.379 --> 00:19:03.220 to use. Basically it prerecords your responses, and we'll 00:19:03.220 --> 00:19:05.320 take you through an example. 00:19:05.320 --> 00:19:10.049 So, spec_helper. The only thing interesting here. We have 00:19:10.049 --> 00:19:13.229 the vcr configuration block, and all we're doing is 00:19:13.229 --> 00:19:18.519 setting a cassette library. So that's basically where these 00:19:18.519 --> 00:19:21.029 responses will be saved. And then we're hooking into 00:19:21.029 --> 00:19:24.350 web-mock, because that's the stubbing library we're using. 00:19:24.350 --> 00:19:29.909 So, here's a spec. And as you can see, 00:19:29.909 --> 00:19:34.169 it's really, really similar to the Facebook graph mock. 00:19:34.169 --> 00:19:36.499 So basically what this does is, you're wrapping it 00:19:36.499 --> 00:19:40.509 in a block with vcr. So vcr, what it 00:19:40.509 --> 00:19:42.629 does, is it goes out to the network and 00:19:42.629 --> 00:19:46.009 makes the request for you, in your testing environment, 00:19:46.009 --> 00:19:48.659 and it pulls that response back and saves it, 00:19:48.659 --> 00:19:52.929 in this case, at Facebook user_arjun. 00:19:52.929 --> 00:19:54.369 And the nice thing about this is you don't 00:19:54.369 --> 00:19:58.090 have to go out and collect your own responses, 00:19:58.090 --> 00:19:59.669 which I find to be pretty tedious and also 00:19:59.669 --> 00:20:03.239 error prone. But, it also means you don't have 00:20:03.239 --> 00:20:08.499 to break airplane mode with your tests, because you 00:20:08.499 --> 00:20:11.070 can run this before, and you can cache all 00:20:11.070 --> 00:20:14.669 of the JSON responses and play them back in 00:20:14.669 --> 00:20:17.559 your build. So when you're running it on Travis 00:20:17.559 --> 00:20:20.009 EI or Circle or whatever you happen to use, 00:20:20.009 --> 00:20:23.369 you're not gonna break your build because of network 00:20:23.369 --> 00:20:27.789 failure. You're going to be using these cached responses. 00:20:27.789 --> 00:20:31.059 And that also just allows you to verify the 00:20:31.059 --> 00:20:33.679 responses. So, like I mentioned, it's a little error 00:20:33.679 --> 00:20:36.090 prone. I've tried collecting these responses on my own 00:20:36.090 --> 00:20:39.059 and, you know, sometimes I copy and paste them 00:20:39.059 --> 00:20:41.549 wrong and come up with an issue. So this 00:20:41.549 --> 00:20:43.580 kind of allows you to, like, have a nice 00:20:43.580 --> 00:20:46.929 programatic way of pulling those in. 00:20:46.929 --> 00:20:51.109 So, there's also an additional build process you can 00:20:51.109 --> 00:20:54.700 add. So, for the NHL example I talked about, 00:20:54.700 --> 00:20:56.590 the problem was there was no versioning. So what 00:20:56.590 --> 00:21:00.029 you can do is, if you want bonus points, 00:21:00.029 --> 00:21:03.080 and you are really dependent on an API that 00:21:03.080 --> 00:21:05.149 doesn't have versioning, you can do some kind of 00:21:05.149 --> 00:21:08.619 build process or, you know, test setup, where you're 00:21:08.619 --> 00:21:11.330 basically running it outside of your normal test mode, 00:21:11.330 --> 00:21:13.970 and you check the casettes for diffs, and verify 00:21:13.970 --> 00:21:17.070 that the responses are not changed from before. So 00:21:17.070 --> 00:21:19.029 this can help you avoid versioning issues. So I 00:21:19.029 --> 00:21:23.710 recommend that if you're using something like NHL API. 00:21:23.710 --> 00:21:26.940 So, the next one we're gonna briefly talk about 00:21:26.940 --> 00:21:31.200 is puffing-billy. And, aside from having a really cool 00:21:31.200 --> 00:21:34.989 name and a nice logo on their GitHub, this 00:21:34.989 --> 00:21:37.960 is an interesting gem to use. We're not gonna 00:21:37.960 --> 00:21:40.440 use an example here, but basically what it is 00:21:40.440 --> 00:21:44.590 is for in-browser requests. So basically if you're having 00:21:44.590 --> 00:21:49.720 integrations that are browser-based, you can record and reuse. 00:21:49.720 --> 00:21:54.509 Just like vcr, and use those responses again. 00:21:54.509 --> 00:21:58.639 So, I don't want you guys to think that 00:21:58.639 --> 00:22:00.429 all of this has to be done in Ruby, 00:22:00.429 --> 00:22:03.999 and that you have to use vcr to first 00:22:03.999 --> 00:22:06.379 record your responses. There's a lot of tools out 00:22:06.379 --> 00:22:11.489 there that will help you to collect these responses, 00:22:11.489 --> 00:22:13.940 test API endpoints faster, and I want to share 00:22:13.940 --> 00:22:17.259 some of those with you. 00:22:17.259 --> 00:22:21.509 So, Chrome Dev Tools. Has anyone heard of this 00:22:21.509 --> 00:22:24.830 in here? Yeah. Probably, probably all of you. But 00:22:24.830 --> 00:22:26.249 this is the first one I'm mentioning because I 00:22:26.249 --> 00:22:29.940 use it, probably every day. Obviously it gives you 00:22:29.940 --> 00:22:33.399 a really nice way of viewing responses and requests 00:22:33.399 --> 00:22:36.559 and resending them. So super useful. I'm not gonna 00:22:36.559 --> 00:22:38.259 get too far in-depth in that one because I'm 00:22:38.259 --> 00:22:41.139 assuming most people have worked with it. But it 00:22:41.139 --> 00:22:42.349 doesn't hurt to mention. 00:22:42.349 --> 00:22:45.590 So next, Postman. If you want to stay within 00:22:45.590 --> 00:22:48.889 Chrome. This is an extension you can use. And 00:22:48.889 --> 00:22:51.799 it basically gives you a user interface around running 00:22:51.799 --> 00:22:55.419 these requests so that you can have kind of 00:22:55.419 --> 00:22:57.879 an easier way to play with re, requests and 00:22:57.879 --> 00:23:00.179 responses. And it allows you save them. It gives 00:23:00.179 --> 00:23:04.729 you, you know, a time in milliseconds of completion. 00:23:04.729 --> 00:23:07.539 And this one I think is, I was working 00:23:07.539 --> 00:23:12.590 on a Tinder API Client for fun, so. That's 00:23:12.590 --> 00:23:15.299 what these requests are for. So, that one's actually 00:23:15.299 --> 00:23:17.729 up on my GitHub, too, if you're curious. 00:23:17.729 --> 00:23:20.419 So, I use that a lot. But if you 00:23:20.419 --> 00:23:23.519 like to stay command line based, I would recommend 00:23:23.519 --> 00:23:29.749 HTTPie. It's basically an easier-to-use version of curl, and 00:23:29.749 --> 00:23:31.970 it doesn't have, like, quite the archaic syntax curl 00:23:31.970 --> 00:23:35.259 has. So, I think it's, you know, worthy. Worthy 00:23:35.259 --> 00:23:37.519 of use. And, you know, it'd be easier, obviously, 00:23:37.519 --> 00:23:39.739 you know, to run a script around this than 00:23:39.739 --> 00:23:42.029 it would be to run it around Postman. So 00:23:42.029 --> 00:23:44.359 if you need to do something more programatic, this 00:23:44.359 --> 00:23:46.649 is probably your best option. 00:23:46.649 --> 00:23:50.340 And, one last tool I really like to use 00:23:50.340 --> 00:23:54.379 is called Charles. And Charles does a lot of 00:23:54.379 --> 00:23:57.289 the same things as Chrome Dev Tools does, but 00:23:57.289 --> 00:24:00.859 it acts as a proxy. So it basically captures, 00:24:00.859 --> 00:24:03.580 you know, requests between you and your network. So 00:24:03.580 --> 00:24:06.249 you can set this up to capture any request 00:24:06.249 --> 00:24:11.090 from your Mac machine, or you can proxy in 00:24:11.090 --> 00:24:13.969 your phone as well. So I found this really 00:24:13.969 --> 00:24:17.259 valuable when I was testing out the request from 00:24:17.259 --> 00:24:20.749 the Snapchat client, because it allowed me to see 00:24:20.749 --> 00:24:22.999 what my phone was making for requests and record 00:24:22.999 --> 00:24:25.489 those. And especially when we didn't know what the 00:24:25.489 --> 00:24:28.570 request was, it was very helpful in that case. 00:24:28.570 --> 00:24:31.690 And it's also cool because, you know, when you're 00:24:31.690 --> 00:24:35.759 building an API on Ruby and you want to 00:24:35.759 --> 00:24:37.969 build on iOS client with it, and you're not 00:24:37.969 --> 00:24:40.129 really sure how often to pull and stuff, I 00:24:40.129 --> 00:24:42.429 sometimes pull this up, and I'll just see what 00:24:42.429 --> 00:24:44.629 other apps are doing. So it's a good way 00:24:44.629 --> 00:24:47.340 of debugging other peoples work and, you know, seeing 00:24:47.340 --> 00:24:51.229 how they're doing it well. So, I highly recommend 00:24:51.229 --> 00:24:54.320 you check it out. It's pretty easy to use, 00:24:54.320 --> 00:24:57.440 and you can use it with SSL requests as 00:24:57.440 --> 00:24:57.979 well. 00:24:57.979 --> 00:25:00.840 So, here's some additional reading. I know you won't 00:25:00.840 --> 00:25:02.349 have time to write this all down. I'll post 00:25:02.349 --> 00:25:07.830 the slides on my Twitter. But, next up, let's 00:25:07.830 --> 00:25:09.719 bring it all together. 00:25:09.719 --> 00:25:12.690 So, we went over the what, the why, and 00:25:12.690 --> 00:25:16.450 the how of testing services. So, we've shown that 00:25:16.450 --> 00:25:19.830 testing services is crucial. They make up really important 00:25:19.830 --> 00:25:22.259 parts of your app, so skipping tests is pretty 00:25:22.259 --> 00:25:25.419 dangerous. I'd have to say, if you're in doubt, 00:25:25.419 --> 00:25:30.190 stub it out. Determine, when you're making choices between, 00:25:30.190 --> 00:25:35.109 you know, web-mock, sham_rack, or puffing-billy, even, you want 00:25:35.109 --> 00:25:37.679 to determine the amount of flexibility the need and 00:25:37.679 --> 00:25:40.190 the amount of extra work you're going to have. 00:25:40.190 --> 00:25:42.989 For example, it probably takes more time to make 00:25:42.989 --> 00:25:47.289 a sham_rack server and have dynamic responses than copying 00:25:47.289 --> 00:25:52.590 and pasting the request you get from the web-mock 00:25:52.590 --> 00:25:54.559 error. So, you kind of just need to look 00:25:54.559 --> 00:25:57.469 at the project you have and determine what use 00:25:57.469 --> 00:26:00.539 case best fits these options. 00:26:00.539 --> 00:26:04.629 And, also, record responses to save time. I wish 00:26:04.629 --> 00:26:06.590 I would have started doing this sooner. It's, like, 00:26:06.590 --> 00:26:11.330 super useful. I would highly recommend you do that. 00:26:11.330 --> 00:26:14.499 And next up, after me, I'd recommend you stick 00:26:14.499 --> 00:26:17.419 around. I had the pleasure of pairing with Austin 00:26:17.419 --> 00:26:20.840 yesterday, and I think his talk plays off my 00:26:20.840 --> 00:26:23.759 talk a lot, in that it talks a lot 00:26:23.759 --> 00:26:26.279 about inconsistent test failures. And he goes a lot 00:26:26.279 --> 00:26:29.539 more in-depth on, you know, other kinds of inconsistent 00:26:29.539 --> 00:26:33.249 test failures. And you just should definitely stick around 00:26:33.249 --> 00:26:35.210 if you have the time. 00:26:35.210 --> 00:26:37.969 So that's it for today. Thank you for taking 00:26:37.969 --> 00:26:40.619 the time to listen to my talk. And if 00:26:40.619 --> 00:26:42.519 I don't get to your question, feel free to 00:26:42.519 --> 00:26:44.450 shoot me an email, or if you just want 00:26:44.450 --> 00:26:46.299 to chat. And you can also find me on 00:26:46.299 --> 00:26:47.440 Twitter. So thanks a lot guys.