Join Kyle Sherman for an in-depth discussion in this video Missing Auto Layout constraints, part of Learning LayoutTest for iOS Development.
- [Instructor] Now we're going to take a look at a new view called Informational View. This is the same view that was used in an earlier video. Let's take a look at the zip file for this. InformationalView.zip. As you see, this may look familiar. It has a title, description, and some type of action button. This is a view that may be shown from the bottom of the screen or as a small modal or something like that. Don't be fooled by the size of this, in actual use it may be much smaller. Let's go the the layout test file, InformationalView layout test.
As you see, we are testing for multiple different sizes, both portrait and landscape. You also see that we've implemented the adjustViewSize method. As you see, we are setting the height based on the width passed in and the content. You also see that we have a method called height for bounding width in the Informational View that will calculate this for us. Let's look at the actual layout test code below. You'll see that testLayout has an underscore in front of it. Xc test requires all tests to be prefixed with test.
I put an underscore prefix so that it won't run this test. This is essentially disabling the test. You could put anything you want here, for instance, disabled, and it will not run. But now, let's run these tests. Take out the prefix, and hit Command + U to run all tests. Oh, man! 108 errors, that is a lot. But, we can fix it. Let's take a look at the issue navigator.
Don't get discouraged. Let's actually come back to our tab over here, but this time we're going to take a look at the issue navigator. Since there are so many errors, it may be easier for us to see this list here. So, as we see, Subview has class UIButton that has no accessibility label, and we see that a ton of times. Well, that seems easy enough to fix. Accessibility is really important to support, it is mostly as simple as adding a label that will be read by the voiceover feature and allows people who are vision impaired to use your app.
There are of course other things to consider with accessibility, but this is the main thing we're covering in this course. So, we're going to fix this by adding an accessibility label in Interface Builder. Let's go back to our code, go to the Project Navigator. Let's go to the interface builder file for InformationalView. Going to click the button, going to go to the identity inspector, scroll down here, accessibility is turned on, and we just need to add a label. Take Action Button.
That's all there is to it, let's run again. Wow, look at that, 108 errors down to four, just with one little change. So this is great, don't get discouraged if you see a large number of errors, it could be one little thing that is an error for every single test. So let's take a look at what's going on now. As you see, in the left here we have Bottom side extends past superview, and we have that four different times. So that sounds kind of familiar. Let's take a look at the snap shot.
As you'll see, if we go to Safari and refresh, this is for the other view, and there are no errors. So, this is not exactly what we want. What we're going to do is, we're going to get the path from Xcode again, copy it, go to the Finder. Let's create a new window that will leave this in, command + shift + G, paste, and now you'll see we have two different folders, one for the View Controller Layout Tests that we were already running, and one for the Informational View Layout test images. So, for this one, I'm going to go here, go to the index.html, and now we see these.
You see the error, Bottom side extends past superview, and as you see here, you may not really notice an issue, but this button is supposed to be 44 points high, and right now the bottom is being cut off. To help expose that, you could also set the background color of the Take Action button and it may make it a little more obvious. We can also verify this by going to the zip file. Back in Xcode, take a look at this button, and we can see there's a constraint on there, for the height equals 44, as I was saying.
So there seems to be an issue in adjusting the sizing based on the width. What we want to do is set a break point, but only when it fails, we don't want to see the sizing method for everything because it's exceeding for most, it seems. So, let's look at a way to do this. Let's go to the issue navigator again. Click on this, one of the failures, you'll see all the failures happen on this one line that actually prints it out. What we can do is, we can set a break point here so it'll only stop then.
Now we want to go to our LayoutTest file. So we want to make sure that we stop only on the one that fails. So in order to do this, we essentially need to figure out at which number test it fails and be able to put a break point in our adjustViewSize method, and this is going to get a little complicated, but it's going to allow you to set a break point only on the time it fails in any part of the code. To do this, what we're going to do is the following. In this extension, we're going to create a new enum to hold a constant, so we're just going to call this DebugConstant.
And in here we're going to have a static var called count that's going to be initialized at zero. Now, in the adjust ViewSize method, since this is where we want to put our break point, because the problem is most likely in the height for binding width method, we're going to simply put DebugConstant.count, plus, equals one. So this will start incrementing it every time this is called. What we'll do is we'll print out this constant.
This will print out the count every time, but we have a break point set only when it fails, so in the console, once it pauses, we'll see that final count. Let's run the tests, command + U. Now execution pauses on the XCT Fail method. Now if we look in our console, we're going to see all those numbers printed out. The last number is 35, so this means that's the count value the first time it fails.
So we're going to take that number, 35, we're going to go back to the code, and what we're going to do is, we're going to add a break point here, but we only want this break point to work if the condition is that the count is 35. So if we right click on this and hit Edit Breakpoint, we can add a new condition, and in this condition, we can write DebugConstant.count equals 35. And that's it.
Now, it will only stop here if the count is 35. Now let's run again, command + U. We stop the current run. Now we see it stops right where we want it on the 35th time, actually the 36th 'cause it's index zero based. Now, we can step into this height calculation method, so let's step over this, step over this, and step into this. Here we are, height for bounding width.
We can inspect the height properties, so we can come down here, we can do po and print out any of the ones we want, such as the titleLabelHeight, try to see if that looks about right for this. We can see what the text was of the label, so let's say titleLabel dot text, yeah, that seems about right, it's a small string and it's 34.
We can also look at the description label. Dot text, so that's a little longer, and the descriptionLabelHeight. That seems a little odd, doesn't it? It's smaller text, but it may not be the right size. Let's take a look at this calculation a little closer. Aha! We're taking the width in, which is the width of the whole view, and we're using that for our text height calculation directly.
But, if we look, we actually have left and right padding on the view, horizontalPadding. So, we need to take that into consideration for the width. To do this, we can make a new property, we'll call it labelWidth since both have the same padding, and here we will take the width but then subtract the horizontalPadding and it's left and right, so we'll multiply it by two.
Now we'll take this, copy and paste, and replace the width and the label height calculations here and here. Let's save. Now I think we fixed it, so let's turn off the break points and try command + U, and running again, just to see if everything passes. Remember we had four failures. Great. Test passed. We fixed the issue. Now you can remove the debug code.
We can go to our break points, and you can actually delete break points from here. So we can delete, come here and delete, and we can remove this code here. DebugConstants as well as the enum at the top.
- Installing the library
- Specifying test data
- Reviewing property-based testing
- Using test data and writing the LayoutTest test
- Testing views at different sizes
- Debugging with snapshots
- Dealing with common errors
- Advanced debugging tips
- Exploring catalog view