Okay guys, so the slot shaft is probably the best spot in this entire game to farm Legendos I Had a question which I needed answering How many legends could I get from this place within five hours? Well today guys, I reveal the results How is it going guys? My name is D.P. General I'd like to thank you for stopping by and checking out my video if you do enjoy it Leaving a like really helps out and subscribe if you want more Borderlands 3 also guys I'm giving away copies of Borderlands to win one for yourself or a friend simply subscribe and make sure you have notifications turned on Drop a like on this video and leave a comment down below So yesterday people uploaded a glitch where you could basically become invincible. I Also later on in a day decided to go into the slot of chefs because I knew it was a great legendary farming spot Because I main Zayn it's pretty difficult for me going there and make him through without dying every five seconds But because I had invincibility glitch, I thought yes, I'm gonna farm this spot I uploaded a video of me basically doing it for about 30 minutes and the amount of legendos I got was Unbelievable it really was but I decided to go one step. Well, I'll take one step probably about 10 steps further. I Wanted to see the results of five hours of farming this spot and that is what I have for you today people Are you ready? Are you ready? Check this out Yes, that's a wall That's a warning sign, but look at my map in that top corner It is jam-packed full of legendos now it's gonna carry on but An enemy kind of well, I think he's trapped under the truck. I can't see him. Well, I've tried a thing I've tried grenades. I've tried shot gunning. I've tried my flak. I've just I don't know where he is I don't know if he's on the roof. I don't know So I probably wouldn't want to Six seven hours, but five it's where I kept out and I'm tired guys Which you could probably tell by my voice But the amount of legendaries is on another level now will say Before I come here. I was farming for artifacts. I had about five or six which I have dropped We should amongst this pile, but even take away six guys.  I did swap That cuts man for the one I've got in my hand because the one I've got in my hand is An anointed version which dropped here So I had to have it anointed perfectly for what I do Well an action skill end weapons that has effect damage and chance are increased by 75% for a short time Can't go wrong with that Now after about the three hour mark it seemed as though Loot stop dropping I definitely wasn't as We kind of come over there because I was getting sometimes when I first started the first hour I was getting probably one or two every one or two legendaries every four enemies after about the three hour mark that reduced massively I was probably getting one every five six enemies, which is crazy because The enemies get bigger and badder the further you go on to this This slot has mold thingy as you guys probably know if you play it. I don't know whether I've Caps out on the amount of loot you can get drop without loading in and out And I've got a glitch Legendary here if you look on my map, it's definitely not that one if I picked out of it still We can still see it there. It's only can't see it now But there's a legendary here, which had dropped through the market It's got an arrow if you look there and you see it slightly to the right of my pointer I'll zoom in. There's a legend there. That's gone underneath the floor So it's glitched what there's one glitch there. And what was that? I just picked up We'll pick that up as well. I don't know. I don't know what I just picked up I don't know what it was. I'm so tired people. I really am Now it's just ridiculous. It really is. But yeah, like I said, I think I did cap out Unlegendaries or Loot even for that now and I can't find out because I can't carry on because that that enemy stuck up there But it definitely seems that way It really does now I'm actually gonna have a look through some of this loot because I do Want to see what's dropped here? Sickle all my days. That's a 92 Zane after stopping places with your digital arm weapon damage is increased by 75% for a short time Let's have a This is the best weapon in the game. By the way, I'm gonna make a video about this. This weapon is unbelievable But we're gonna swap you I'm gonna equip this thing here. Oh, that's pretty cool. Oh, is it a shotgun? Well, I didn't know that I Was looking at that and I didn't even notice didn't even clock that We'll try you out. We see what you're all about. We'll see what you're all about Unending Magnum. I wonder if I got a loosens core around here. Oh Eliuda That would be pretty epic Storm from grenade. Actually, no, I've never actually tried one of them Now don't worry I got no grenades because there's another glitch where if you Press your action skill button and then press your inventory button at the same time Your action skills pop up. I mean your kill skills pop up at the bottom of the screen as you can see there and I've got a grenade regen Action skill or kill skill. Whatever. You see my grenades are regenerating so I can check what this is like It's like a firework It really is Yes, you won't see it's true effect Until a well until a friend and then people hey, oh, I thought as a load and this is a joke Oh, I've read a weapon. You only need to fire once reference to Ironman Ironman one where you called his missiles to joke. Oh, and it said that exact thing When he's in the desert, you know, you know people Hunt some jackhammer Let's try you as well. You sound pretty cool.  Let's have some Jack. That's amazing. I'm reload It could be on clip empty. I went I went I Went here in things then people I know I'm I know I'm tired, but I went here in things then That's you were the same thing. I definitely heard him. I Probably going mad I'm probably going mad people I Haven't come across a Load or Lucian's cool Very an echo. That looks pretty epic. What? Yeah Yeah, but you don't need you Rowan's course a good weapon turbo frozen 10 gallon Oh Lucian's cool baby a 90 beast master. I don't have a beast master Well gamma versus active gain 65% bonus radiation damage, you know, I'll take it Anyone of my friends want it. I'll give it to them another Jericho. There's just so many weapons in this game guys It's unbelievable. It really is what we got here. What have you got here? Shocking a a it's not a bad weapon Super Mario gun Another Lucian's cool. I don't know if you guys have seen my my ones an absolute monster It's somewhere here wagon wheel did I pick that up? I must have There's my one It's that my way. Yeah, that's my one there I'm not just go and the next two magazines will have 50% additional bonus radiation damage With that paired with well to the next two magazines Considering critical hits return to bullets back to your magazine. You don't have to reload if you hit in quick shots So you basically got 50% additional damage For an infinite amount of time to reload twice, which is crazy I've already stacked. I didn't get a lot either. That is ridiculous people It really is. Oh That's anointed to me. I'll take you. Thank you very much. I Will oh Another one I wanted to make. Oh, I got I got a collect 10 people got to collect every anointed weapon to oh There we go 24 in a mag Let me compare that to my one. Have I got mine on me? Well, I thought I had mine on me And there we have let me put you down there So I've got less bullets in a mag Wow, it's got more damage than mine as well more damage bigger magazine size faster reload That is crazy people But mine's anointed Mine's anointed and it's monstrous man You know, I'm still gonna take you I'll take you and show you Loaders on months. He can't leave them about Can't leave them about people Dastardly Maggie. What about it's another one for me? What oh, yes, that looks Beautiful. Oh There we go. Oh, yes, that's amazing. That's amazing. I'll take you every day of the week The speed loading how walk I don't know if you guys have heard this. I've got one. I'll put it on.  I really do Put you there. It sounds incredible It's known as a doom shotgun Bingo It's epic. It really is Now where is this guy? I ain't got a clue where this dude is, but he's hiding somewhere I mean, I tried everything. Is he up there on that roof? I'm on top of him here Hold up. Does it see an enemy then? Nice It's a shotgun slug thingy bubs popping out my gun. I'm so tired guys So it get for firing things for five hours straight After making about four videos.  But yes, as you can see guys, I'm invincible. I can't die. I can that day Yeah, I can that day. Oh What is this?  Yeah, that's craziness Is that another Lucian's call there? Is that the one we looked at already? I don't want to look that was over there Try all that. I don't need it. I don't need it. I'm not looking at it.  Oh, I'm sure it can change the ways it can for mortar Could check that out. I think the monster I have got one in my mouth. No, it's on my wall It's on my wall And I made a video about ages ago But yeah guys that is it. I mean these are the results of Five hours of farming. I'm pretty sure I reached my cap Unlute that can drop I really do Now I would gather it all up and put it into one corner But that would take me forever because I've hardly got any space inside of my inventory and I just can't be doing that people Can't be doing that people. In fact I'll do it. I'll just pause the video. I'll do it. I drop all my loot. I've got army in one corner I'll pick it all up Pull it all together and see what it looks like. So give me about well done I cut the video back in a sec and guys Well, it took a lot longer than I expected. I've cleared out the place of legendaries None of them are all right there.  There really is There's a load now you can show okay. Well, I can show you the one that I was talking about earlier now See I've it's glitched. I think it's gone somewhere Unless it's up there, but I'm sure to the glove Nope So, yeah guys, there's five hours worth of farming the slaughter house or the slaughter shaft And it's just ridiculous people it really is Should I collect the purples and put them there as well? Yeah, why not? I'll be back guys. I'll be back Oh man, this was a mistake. What am I doing? It's so many And guys we are done. I have cleared out the whole room of Everything I got to drop and I've piled it up into this corner, right? Yeah and I mean I'm not joking guys that took me about half an hour to do that I mean look at the amount Of epics I had I mean some of these could be decent weapons. That's the crazy thing about it.  I'm just gonna quickly run back and grab mine Before things start de-spawning because that will be awkward It really will And I've got things here that can't lose Don't know what that purple was probably my weapon that keeps um Going back to epic Then going to legendary again. They're back to epic into legendary, but look at that guys Wow Ain't that a pretty sight and guys that is it that is the results Of five hours Of killing enemies Absolutely ridiculous.  I really do Thanks as always for stopping by and hopefully guys I will see you on that next one


All right. Jennifer, they just announced in Austria, they're going to mandate the vaccine by February. Do you think that that could possibly happen here? I think it would be very difficult here. I mean, what happened in Austria is the first step was they wanted to lock up in a sense, they wanted to lock down the unvaccinated. So, which is unbelievable. So they wanted to basically say unvaccinated people cannot leave their homes. Unvaccinated people have to be under lockdown. You can only leave your home. You know, the police would be able to stop you in the street and ask you to show a vaccine card for you to even be outside. Now, that is of course not. And I think there was such a backlash to that and the ridiculous nature and the nature of that is they went, they need to solve that and the solution for that is, you know, we're going to force everybody to get a vaccine and then we don't have to stop in the street because everybody will have to have a vaccine. I guess they'll tattoo it into their foreheads.  I'm okay. It's just, it truly is unbelievable what the Austrians are doing. It's, it's super surprising. You know, it's going to be interesting how people interpret it. The Germans might do the same. There's talk in Germany about mandating vaccines. What other countries in Europe, what they've done here in Puerto Rico is instead of mandating you get vaccinated, they've made it very difficult for you if you're unvaccinated. So for example, you know, in France, you have to have a vaccine passport to go into restaurants to go into stores to go into public areas. And basically vaccination rates went way up because once you force people to, once you required it at the government level, people incentivize to get the vaccine, whether they, whether they wanted to or not.  It's gone put any, and if you look at the stats, I think, I think Matt was saying this, I mean, if you are vaccinated, your probability of dying from this is, is the flu, less than the flu, even for old people. This is not, you know, if you're vaccinated, you're fairly protected. The vaccine diminishes over time, the effectiveness of vaccine diminishes over time to get a booster. You probably have to get a booster every year. That's just, you know, it's another, it's another flu for those who are vaccinated. And there's also reason to believe that over time, COVID will become less deadly. For if you're unvaccinated, maybe you get sicker.  Why is it any of our problem? Right. So unfortunately, it turns out the vaccinated people get COVID. Unfortunately, it turns out that vaccinated people can infect other people with COVID at a lower rate than unvaccinated, but they still can. So the whole thing is a mess. It's a mess because of communication. It's a mess because people don't understand data. It's a mess, which I've been saying from day one, it's a mess. Because the state, once they impose zero risk on all of us, are they going to mandate that we get the booster every single year? There's no end to it. But what they learned from last year, from the lockdowns last year, is that they can get away with anything and that we would roll over. Now there are major demonstrations in Europe right now. I just read a headline from the Netherlands, from Holland, yesterday. And I haven't read the stories. I don't know what the details are, but there were demonstrations and the police were shooting people. So I don't know if they were using live bullets or rubber bullets, but at least it sounds like the Netherlands, they know how to break up a riot. But this was a demonstration about not accepting lockdowns. Finally, people are starting to wake up to the need to resist lockdowns and it's becoming violent. And I think if Germany mandates this, there's a huge segment of the German population that is going to demonstrate a riot. And so it's of course very politicized. The right in Germany, the anti-vax right is filled with all kinds of characters on the right over there. So you get this mixture. You have to be careful when your anti-vax mandates, because then you might be associated with some crazies on the right. It's all, you know, it's so politicized and so messy and so anti-non-scientific and so authoritarian and so status that the whole thing is a mess and a disaster. There's going to be more and more demonstrations. There's going to be more and more conflicts and standoffs in Europe. It's going to be very interesting. I mean, to see how this all pans out, one of the interesting things about Austria is if I'm not mistaken, and maybe I am, but I don't think I am, is that the government in Austria is a right-wing government. This is not, you know, and I wonder how people are going to explain this as a left-wing conspiracy, that the whole COVID thing was a left-wing conspiracy. So many people in the right in the U.S. believe that somehow lockdowns, mandates, vaccines and everything were left-wing conspiracy. Then how come the right in Austria of all places is about to inflict the mandate? So it's just bizarre. Yeah, but Yaron, don't underestimate how people can twist things around to support their conspiracy theory. For example, one thing popped into my head, the right's clearly been infiltrated by the left in Austria. That's what's going on. It's all just the left now. So that just proves how effective this conspiracy really is, the fact that now a right-wing government is doing things associated with a left-wing conspiracy. There you go. You see, the contradictions are beautiful, though, because one of the most admired figures among the right today, and particularly the conspiracy theory right, is Orban, the president of Hungary and the Hungarian right, because he has shut down the media, he's shut down the left, he's shut down everything. He closed the border to these, you know, to Muslim immigration. He's the hero of Tucker Carlson and many on the right. And Hungary's had lockdowns, vaccine mandates, you know, all these things. So I wonder how they, but you're right, they always find a way around it. You know, Orban is confused on this issue. He's got some leftist advisor, or he's trying to manipulate the left. He's outlifting the left. You know who knows. We could really control our brains to find ways in which conspiracy theorists can justify what they've come up with. Thank you for listening or watching The Iran Book Show. If you'd like to support the show, we make it as easy as possible for you to trade with me. You get value from listening. You get value from watching. Show your appreciation. You can do that by going to Iranbrookshow.com.  Also, if you'd like to see The Iran Book Show grow, please consider sharing our content and of course subscribe. Press that little bell button right down there on YouTube so that you get an announcement when we go live. And for those of you who are already subscribers and those of you who are already supporters of the show, thank you. I very much appreciate it.


Hi, Jeff Rick here with the Cube. We are on the ground at Spark Summit 2015 in downtown San Francisco and we're joined by this next segment by Ariana Grattow, Queen of CrowdChat, SiliconANGLE Media. Ariana, welcome. Hey, thanks for being here. So you've been a very busy lady the last couple of days, really kind of driving a lot of social action around Spark. So I wonder if you could talk about, first off, kind of what has been the social mojo around Spark and all the IBM announcements today and, of course, a lot of action here at Spark Summit. Yeah, definitely. It seems like Spark is a trending topic. Last week we were at Hadoop and a lot of the conversations on social media were about Spark. A lot of the conversations in at the summit were about Spark and it's obviously an important topic. I'm finding that people are really interested in this new platform, especially IBM, who announced yesterday they're launching all of their, they're launching an entirely new team in San Francisco and they're going to be using the software for a lot of their new developments and training a lot of new developers on the software. So it's definitely a trending topic. I've been using CrowdChat personally to kind of see who's an influencer in this new area, finding people through the backend data, who's talking about Spark, who's interested in this topic, and who's active on social. So if you're active on social, I might just reach out to you and get you on the queue. So talk about kind of the CrowdChat app. We often talk about it as kind of a container. How that type of a social experience and the level of engagement you can achieve there with the thread of conversations, bringing in Twitter, LinkedIn, and of course Facebook. Difference in kind of your typical kind of Twitter stream that flies by, you know, question one, answer one. How does the app really change kind of the level of engagement, kind of the touch with the other folks? Well, if I had known this question, I would have done a demo. No demo. We only got five minutes. Okay. Well, the backend platform is kind of monitoring. We have an algorithm. So we're looking at specific keywords and hashtags that people are using and targeting like a broader community in general. So for this, obviously, this community would be the Spark community. So we're looking at big data terms, Hadoop, people who are using Spark, Hadoop, and trying to see what they're using in the community. And then we're looking at trending hashtags within that. So today I looked. It was big data, Hadoop, Spark, IBM, Insight was trending. And yesterday the Cube was trending because we were pretty active on social. So just seeing in real time what's going on, then we're able to look at what people are saying within the community. And we're also able to search by job title, job description, anything in their keyword. So often I do, I search by mom for all those women who I may have Twitter harassed. I look at moms and I'm kind of key wording the term moms and tech, finding specific moms in each community, highlighting that they have two jobs in the world and not just a specific job. And, you know, kind of tapping onto that whole Anita Borg, highlighting the women that are doing a little bit more and above and beyond the typical range. So that's my new thing. Moms and tech. Okay. That's all great tech. But what I'm more curious about is really the way that you can actually engage people, the connection that you make with people in this type of an atmosphere versus kind of this ethereal Twitter stream that kind of flows by and off it goes. When you have this type of a platform that really contains a conversation in really a room, a place, as opposed to just kind of fleeting by. Do people connect closer? Is it a tighter level of engagement? What do you think? Yeah, that's great. I thought you were talking about the back end platform for the first time. For the regular crowd chat platform, it's a conversation platform and people can log in through Facebook, Twitter and LinkedIn. Everything's sent to Twitter with the hashtag appended. So for that platform, you're having a closed area conversation about a topic that's important to you. So if I'm interested in Spark, we can have a conversation about Spark and I can through the platform know that you or whoever's logged in is also interested in that. Maybe you're talking about something that I'm working on and I can directly engage with you through the platform because I'm seeing that you're working on this. I'm working on this too. Let's talk personally after this. You can make a lot of deep connections directly through the platform and you have a place to discuss. So you may be able to talk to people that you might never be able to talk to in real life or you might not even know exist. Okay, so last word. How can people learn more about crowd chat? Where do they go? Well, first, you can find me on Twitter at at ariana grado, a-r-i-a-n-a-g-r-a-d-o-w. And you can also go to crowdchat.net. And that'll, there are lots of upcoming chats. We have a live chat right now about Spark Summit and we'll be following the cube throughout the entire calendar year doing crowd chats for every cube. So just follow along either at crowdchat.net or silk on angle.tv. Excellent. Well, thank you very much. As we like to say, join the conversation. I'm Jeff Frick with a-r-i-a-n-a-g-r-a-d-o-w. We are on the ground at Spark Summit 2015 in downtown San Francisco. Thanks for watching.


So I started presenting at Iowa's Death's Goat Meetup one year ago in January and I kicked off my presentation by introducing myself in Mandarin and with every other presentation I wanted to introduce myself in other official languages in Singapore. So one year ago it was like this, Ni hao, wo zia o machi, wo shi chonk, Poland. Next time I introduce myself in Bahasa. Halo, na masaya machi. Saya berasa dari Poland. And I promised that the very next time I'll introduce myself in Tamil. Which is kinda difficult. So let me try this one. Vanakam, jen peyer machi. Nan wuri, Poland kudimagen. Hello everyone, my name is Machi and I'm from Poland. And I run a blog called Switching IO. You can check it out. We write about Switch with my friends, about unit testing and iOS related stuff. And today I will be presenting about unit testing. On a daily basis I work for BBM. BBM is a messaging application. And what's great about working at BBM is the way we work. And the way we work is we use extreme programming. We do per-programming and test-driven development. So on a daily basis I do not write code on my own. I have a colleague who I work with. We have one workstation which has connected to mice and to keyboards. We solve problems together. We try to come up with the best ideas we share knowledge. And we also use test-driven development. So we write unit tests first for our source code. And then we implement the desired behavior for the application for objects. So this presentation will be about synchronous unit testing. But first, let's imagine you are working for a messaging application and you are given a task from your product manager. And you are told to load all the messages that user got when application launches. So we have this struct that represents messages that were sent to our users. Message has an author, a text, probably an identifier. And we are given this protocol called message-loader. It is just one method called load. And it has some callback that takes an array of messages. It's an argument. So this probably tells us that this is an asynchronous operation. And we have this message-loader class that confirms this protocol. It implements the load method. And for simplicity, it just invokes callback with an empty array of messages. But it's okay for us at this moment, at this stage. Let's implement this behavior we wanted to have. So we need to load all the messages when application launches. So first, let's initialize loader on the application delegate on an object that confirms this protocol. We have a loader. And we need to call load when application launches, right? So let's call load. And that's it. We can maybe print. Guess product manager didn't tell us what to do with it. It doesn't come up for some reason. That's okay. But as I told you, in BBM, first we write a unit test. Then we implement the behavior. So in test-driven development, we call this red-green refactor rhythm. First, we need to write a test that fails. Then we implement the behavior that our test tests. And then we are free to refactor when our tests are passing. So let's write tests first. Some terms for you. SVT refers to a system or a subject under test. It's good to have a common name for every test case that describes object that we currently test. Guess if you have 500 of files with tests and in every test, object under test is named differently, you get good luck with finding which object is tested. So SVT in our test refers to object under test. We can also divide the test into three phases. Arrange, Act, and Assert. So in the first phase, we just initialize our SCT. We set it in a certain state. Then we perform an action on our SCT. And after that, we can perform some assertions. Something should happen with our object and we can assert that the wanted behavior actually happened. So our behavior, load called in application, will finish launching with options. So let's create a mocked message loader that allows us to test the behavior. So let's create this class, message loader mock, NetConforced or message loader protocol. Again, we need to quickly implement a method called load. And let's call our callback with empty array of messages. And because it's a mock, it's good to test that this method was called. And we can do that by introducing some Boolean variable. And whenever our method will be called, we just set this variable to true. So state will change from false to true and we will be able to assert that this actually happened. So then we need to write our unit test. So in our interface, let's create our SCT, which is the type of UI application delegate or rather a delegate. Then we can create our mock loader. And we can replace, oops, we can replace loader on our SCT to the mock loader. And we can check here that actually a value on our loader is false. So the method wasn't called. And our action at this stage is application will finish launching with options on the SCT. But we need an application object. So let's tag our UI application short and we can use this one. So let's perform an action. Application will finish launching with options. Let's supply it with an empty dictionary of options. And now we can assert that actually this action we wanted to happen happened. So we have this test and our application sort of crashed. I'm using SCT assert macros, but test doesn't work in the same way it works in SCT subclass because it's a playground. So I can only get that an assertion took place. But this tells us that actually we need to implement the desert behavior. So we wanted to pull this load in our method. So let's do it right now. And our test should disappear. I mean the warning or error should disappear and it did. So this was TDD approach we followed. And thanks to this TDD approach we can describe behavior by writing unit test. We don't have to comment our code because tests will describe our behavior of our object. And this is actually a failsafe for changes that someone may introduce in the future to our code. But world of iOS applications is not simple because it's an asynchronous world. We usually use main thread for helping UI or changing something on the user interface. But we should dispatch heavy tasks on background threads. I can use for example dispatch queue which is a swift wrapper for ground central dispatch. And we can think of a queue as if it was a thread because every queue usually has a corresponding thread. So I'll be using these terms interchangeably. Again we have this method loader protocol which tells us that this operation will be an asynchronous operation. We also have message fetching protocol which returns an array of, and it has this fetch messages function. And it returns an array of messages. And this method declaration tells us that this will be an asynchronous operation. Not asynchronous but synchronous. So let's introduce message store object that confronts this protocol. Again we can use queue and empty array as a return value. We have our message that was introduced previously. Let's say our product manager told us that it would be nice if we welcomed our users with some welcome message. So here it is and we will use it in a moment. Let's implement message loader. It has store from which it will fetch messages. And there is our load method. Here we use dispatch queue.global and it returns, actually this call async will dispatch a work that's contained in this closure. It will dispatch it to the main thread. We will simulate heavy operations by sleeping the thread for one second. And then we will return whatever store returns to this callback. So let's write the standard unit test and let's see what happens. We write unit test by subclassing xctest case. And usually we have this SUT in every test that we initialize in setup methods. And we clean out after a test and turn down method. Let's test that at least one message is returned on load. So SUT is our message loader. We have a container for fetching messages. We perform this load method on SUT. We get some messages. So let's assign them. Let's assign fetch to messages array. And then we can assert that actually we have at least one message. Now our assertion should fail. So test this red over here. Oh, it's not surprising. It is. Good. Let's implement the behavior on message loader. So let's return here our welcome message. And this red guy here should disappear. No, it didn't. Something is wrong. Still something is wrong. What's wrong? Code run asynchronously. So we can notice that by paying attention to walks, or it fails because of the different reason. Just bear with me a moment. Good. So we make this assertion in line 200. So execution order of execution is like this. We have an assertion of the main thread. We print messages which are empty. And then we assert that it isn't empty. And clearly it fails. And maybe if I run it again, it will show us the background thread. So the callback is called asynchronously somewhere later. And only after that, our messages change. So how can we test asynchronous behaviors, asynchronous code? We need to use XC test expectation class. Then we have this stack that was presented a moment ago. So message loader, message store. And we have our tests. So how can we use XC test expectation? We just need to create an instance of XC test expectation. And it has this initializer with the description that we can use. So still our assumption is that the callback should be invoked with at least one message. So whenever a callback gets called, we can assert actually that messages contains at least one message. So let's assert message as empty equals false. And if assertion is okay, if test passes, we can fulfill our expectation. And then the last thing we need to do is we need to wait for this expectation for a certain timeout. So let's wait for just a second because we select it for one second. And our test should pass. And we can, again, see the logs, how the execution goes on the main thread. So we start our test. We have this call here main thread before wait. Then we enter our callback and the background thread. We can print our messages. And then we have this statement for... on the main thread again after the wait. So actually this wait blocks our main thread for two seconds and probably pulls if the expectation was fulfilled. Then we finish the test. So what are the drawbacks of this approach? At triple length, our inject assert is not clearly visible. This is the first drawback. The second is, of course, code runs asynchronously and we don't have full control over it. And it adds some overhead. Execution might be longer, especially if we deal with lucky tests and somebody increases the timeout. If we increase timeout for 10 seconds and we know that this test failed, we would have to... our running timeout unit test increases, basically. So unreadability. We have this assert phase, somewhat indented in the callback. It's not clearly visible. And we don't know actually how to test... how to name this phase waiting phase. It's not an assert phase. So who knows? Then we don't have full control. We don't know when the callback will be invoked. And we also don't know what the volume of the timeout should be. I've seen a dozen of timeouts of 10 seconds, 20 seconds. And the majority of times there should be less. And we have this overhead of execution. So if test is lucky, never increase timeout. Timeouts should be somewhere around 100 milliseconds. But we can do better than that. We can run our unit test synchronously. So let's do that. Again, we have the same stack of messages, loaders. And we can introduce a protocol. Let's call it dispatching. And it has this one method called dispatch. And it takes an argument, a closure of a work to dispatch on a background thread. Let's create a common superclass for other classes. It contains a dispatch queue. So every SAP class will get this initializer if it inherits from the dispatcher. And let's introduce an asynchronous dispatcher. An asynchronous dispatcher inherits from the dispatcher class. And it conforms to this dispatching protocol. By implementing this method, it executes job asynchronously on a queue, on a dispatch queue. And asynchronous dispatch means that we just put stuff to this queue and it will be invoked somewhere in the future. Or executed somewhere, sometime in the future. We can also have a synchronous dispatcher. And this time job is executed on a queue synchronously. Synchronous dispatch means the calling thread. So the thread that calls this sync method on a queue waits for execution of job dispatch to this queue. And only after it finishes, execution of program goes to line 139 and returns from the function. So our message loader changes a bit. Now we have a queue that conforms to this dispatching protocol. And this class only sees an interface. So class knows that it can call dispatch on a queue. And that's it. So we initialize this loader with a queue. And in the load method, we'll change, we just call dispatch instead of dispatch queue dot global dot async. And nothing else changed. We can also add some syntactic sugar to our async dispatcher. And sync dispatcher, we can pre-populate some let's call them queues or dispatchers. So you have access to main queue, to global queue and background queue. And we can do the same for sync dispatcher. And now the last part. In our tests, we just need to set a synchronous, sorry, asynchronous, doesn't sound good. Synchronized dispatcher. Let's call it background. And we can use global queue or background queue. And we just need to switch queues. So RSUT has this queue property. Let's use this background synchronous dispatcher. And something doesn't work. Synchronized dispatcher to the background. Oh, it's dispatched queue. It doesn't look like this. So what I wanted to do is to use background queue. Here. And it should compile. And here in ActFace, actually we don't need to do anything because this code will run synchronously. So what we need to do is just to make an assertion in the assert phase. So let's do that. Again, we want to assert messages aren't empty. And if I did everything good, it should work. As we see from the logs, we start the test. We have an arranged phase on the main thread. Then we have an ActFace on the main thread. Our callback gets called. On the background thread we print our messages here in the callback. And then we enter assert phase on the main thread. So we have full control over the execution of the unit test. What happens? Unit tests are run on the main thread. So we run our test at least one message on load function. Then it calls load on our SUT. Then our SUT dispatches job to the queue. And that was it synchronously. So we have this background thread. It performs some work in background. The main thread waits for the background thread until it finishes execution. And then the background thread calls completion block, completion closure with messages it fetched. And it's all synchronous. So this one thing we should be aware of when using this approach that work. Imagine this situation. We have this load method on message loader. But this time we want to get job done synchronously on the background thread. But we want callback to be invoked on the main thread. Similar stack as we had previously with message and all the protocols. This time our message loader would look differently. We have main queue in background queue. And initializer gets this queue gets this queue and sets them as properties. Our load method now dispatches job on the background queue but dispatches callback on the main queue. Actually I didn't say whether that will get. So in multi-threading for all the deadlock can occur whenever one thread enters a waiting state because it dispatches for example job synchronously to a different thread. And if this secondary thread tries to dispatch something synchronously to the first thread and it also enters waiting state we have a loop. Every thread waits for another thread to finish its execution but it cannot because the dispatch works synchronously to each other. We can have deadlock in our message loader when we use synchronous dispatcher on main queue. And we can also break it. So this is the image that shows the situation. So we have this synchronous dispatcher to the background thread but then background thread dispatches job synchronously to the main thread. And because main thread didn't finish previous operation and waits for this thread to finish the other cannot finish as well. So situation with no deadlock how can we break it? We need to create two queues first of them let's start with background so again we can use same dispatcher the background for that but for main queue we will instill our test run synchronously so what we need to do is just to dispatcher to switch queue queues we will use global queue as the main queue I'll use the variables and then we need to switch those queues on our SUT so we will use this global queue as our main queue and still background the background loops compiles and again the last thing we need to do is to make an assertion that our messages are open and empty and we can see from the logs that code still runs synchronously and maybe if we want it will please come around this run so we have main thread main thread then call back on a global thread and then again insertion in the main thread again we have full control of our tests and we don't have any deadlock because we used three queues the main thread on which unit tests are run then they dispatcher synchronously to a background thread which dispatch call back to another background thread so I'll take away for you asynchronous tests are unreadable can give some overhead we need to manage timeouts for them and we don't have full control over asynchronous tests synchronous tests has readable arranged arc and assert phases there is no need to increase timeout whenever a test fails and we have full control over them so that's it any questions? yeah it can be yours I remember that there is another question since you mentioned that you guys practice pair programming right so how does this unit has come to practice so the question is how much do we practice unit testing and TDD and how effective is pair programming compared to the traditional solo programming so I think the best benefit you can get benefit you can get is that we learn from each other we have different background and it's better to have two pairs of eyes at the same code because you can one person can see things that the other person does not and we don't for that reason that we use pair programming we don't top into code review process because basically pair programming is sort of a code review depending on the future or you do it after you finish depends on the future because of course TDD demands having some knowledge about the platform so if you are a very experienced developer you can just dive into writing test first and then implementing the feature if you know how to implement it in advance there are times when you just don't know and you need to play around do some spikes to implement features but the majority of times we write test first then we implement the features or whatever the task is and what it gives us is simple implementations and we can also write tests for edge cases for our source code these were two questions yeah so in the synchronous test case we ran into the possibility of deadlocking one rapidly by introducing additional queues why not go the other way since you are already blocking the main queue to do all the synchronous executions why not just run everything on the main queue and never have deadlocking maybe it doesn't matter much that could be I haven't thought about it this is why thanks what would you like to test I can get this part I created a target action method so is there a way to who you need testing on this kind of method because the return is like being returned to another function I cannot think about it at the moment but we can discuss it after the presentation I can come up with another thing at the moment any other questions so your example mock a third party service you mean the message loader yeah you can think about it how detailed are your mocks how detailed are my mocks so it's good to describe the interface remark in terms of protocol so you can conform to this protocol and implement all the methods and you don't need to have all the checks for boolean variables that method was called or wasn't it depends on which methods you use on the mock objects actually at the moment we don't have much script code we use Objective-C and we can tap into OCMock to perform some studying and checking some values and assertions because sometimes I find my mocks need tests now because they are so complicated now some mocks should be I think they shouldn't contain any logic just boolean values toggle and what else I previously wrote for example I had to describe a certification center in terms of protocol so I left empty implementations for any methods I didn't use but I was able to describe a certification center in terms of protocol and I was able to check only parts of the implementations I used any other questions so let's call it a day thank you


This study proposes a spatiotemporal downscaling framework for estimating hourly population dynamics in Beijing using remote sensing and social sensing data, which can be transferred to other regions and is useful for emergency response and studies about human risks to environmental issues.