Test Application by looping through a pattern of values in UITextField - objective-c

I want to test my application by entering values from 1 to 10000 in a UITextField and pressing a "Go" UIButton.
And know conditions where a segue is getting performed.
How do I define the test criteria for automating testing with values 1 - 10000 being entered into the UITextField?
Another situation exactly matching my problem:
While testing a calculator application, I need to check all the possible operations and numbers. Can we do automation to test random clicks on calculator and check the output?

You can use a loop to try each value between 1 and 10000. For each value, type it into the text field, press the button and see what happens. I'm not sure what you're expecting to happen, so I have just written code which checks that a label appears - you should change this to whatever you think would assert that the correct outcome has happened.
XCUIApplication *app = [[XCUIApplication init] alloc];
XCUIElement *textField = [[app.textFields matchingIdentifier: "myTextField"] elementBoundByIndex: 0];
XCUIElement *goButton = [[app.buttons matchingIdentifier: "goButton"] elementBoundByIndex: 0];
for (NSNumber i = 1; i <= 10000; i++) {
NSString *n = [NSString stringWithFormat:#"%d", i];
[textField tap];
[textField typeText: n];
[goButton tap];
// Define what it is you expect to happen
BOOL expectedOutcome = [[app.staticTexts matchingIdentifier: "myLabel"] elementBoundByIndex: 0].exists;
XCTAssert(expectedOutcome, [NSString stringWithFormat:#"Unexpected result for %d", i])
}

Related

Making a simple quiz game. Stuck with the arrays part

I'm trying to make a game with 2 views, the first view has buttons which segues to another view. Depending on the segue identifier, it loads an image which the player has to guess.
I also have a an array which lists hints for the 4 images.
With the array, i made a button which shows the hints on the view, but the problem I have right now is that I don't know how to set the correct array to the image/puzzle.
A code that works right now is this:
if ([self.thePuzzle.name isEqual: #"lion"])
{
NSArray *hints = [lines[0] componentsSeparatedByString:#" "];
self.hintLabel.text = hints[0];
}
But after adding another line for the second image/puzzle, the app crashes.
2nd UPDATE: code that crashes
After entering this code
if ([self.thePuzzle.name isEqual: #"penguin"])
{
NSArray *hints = [lines[1] componentsSeparatedByString:#" "];
self.hintLabel.text = hints[1];
}
The hint button works for the 1st code, which has the lion picture, while the second part of the code, for the penguin pic, crashes when the Hint button is pressed.
3rd Update: Additional information
I made xcode access a file from the internet which contained the words for my array.
This is how i coded it.
[super viewDidLoad];
// Do any additional setup after loading the view.
self.imageView.image = [UIImage imageNamed:self.thePuzzle.imgFileName];
NSString *urlString = #"http://m.uploadedit.com/b032/1395295852132.txt";
NSString *contents = [TextFileManager readStringFromURL:urlString];
//parse contents
lines = [contents componentsSeparatedByString:#"\n"];
for( int i = 0; i < lines.count; i++)
{
NSString *line = lines[i];
NSLog(#"%d: %#", i, line);
}

Programmatically change the state of a UIButton

I've got a pop-up view that loads when a user clicks on a TableView with Core Data elements. On the pop-up view I have a label that represents an int value.
The pop-up view has two butons, one for decreasing the value of the label by 1 and one for increasing it by one. So + and -
What I want to do is to disable the minus button if the label's value is 0. What I've tried is:
-(void)viewDidLayoutSubviews{
NSString *daString = currentVal.text;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:daString];
int number = [myNumber intValue];
if (number==0)
minus.enabled = NO;
else
minus.enabled = YES
}
The problem with my code is that the button stays disabled after I increase the label's value, and it's no longer equal to 0.
Any suggestions?
You should keep a reference to minus button e.g.
#property (strong, nonatomic) IBOutlet UIButton *minusButton;
Set it with a value of your minus button, or connect outlet in Interface Builder
in your action handler for plusButton, do something like that
-(IBAction)plusAction:(id)sender {
//Do your business logic
...
self.minusButton.enabled = YES;
}
//In your minusButton action handler
-(IBAction)minusAction:(id)sender {
//Do your business logic
...
NSString *daString = currentVal.text;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:daString];
int number = [myNumber intValue];
if (number==0)
self.minusButton.enabled = NO;
else
self.minusButton.enabled = YES
}
It seems like you have things the other way around. I would take a totally different approach:
Keep an instance variable (which we'll call 'count') in this viewController which holds the number. it can be an NSInteger. now add a target (self) to both buttons with a #selector(buttonPressed:). now this is how this selector should look like:
- (void)buttonPressed:(id)sender{
if (sender==plusButton)
self.count++;
if (sender==minusButton)
self.count--;
label.text = [NSString stringWithFormat:#"%d",self.count];
minusButton.enabled = (self.count>0);
}
I would just do this with a UIStepper, instead of the 2 buttons. You can set properties right in your storyboard/IB file that specify the max and min, increments, and a bunch of other useful things too. There are a couple video tutorials posted on YouTube that probably cover everything you'll need to know to use it.
Also, I have noticed one thing that...
If the button in disabled state and you are trying to change the title of normal state, it wont work.
I had to change the state to enabled and then I could manipulate title and set back to disabled.

CS193p-Adding backspace to a calculator

I recently started following the online course on iPhone development from Stanford University on iTunes U.
I'm trying to do the homework assignments now for the first couple of lectures. I followed through the walkthrough where I built a basic calculator, but now I'm trying the first assignment and I can't seem to work it out. It's a follows:
Implement a “backspace” button for the user to press if they hit the wrong digit button. This is not intended to be “undo,” so if they hit
the wrong operation button, they are out of luck! It’s up to you to
decided how to handle the case where they backspace away the entire
number they are in the middle of entering, but having the display go
completely blank is probably not very user-friendly.
I followed this: Creating backspace on iOS calculator
So the code is
-(IBAction)backspacePressed:(UIButton *)sender {
NSMutableString *string = (NSMutableString*)[display text];
int length = [string length];
NSString *temp = [string substringToIndex:length-1];
[display setText:[NSString stringWithFormat:#"%#",temp]];
}
My question is shouldn't I check whether my last is a digit or operand? If operand, no execution and if digit, remove it...
First of all, there are several unnecessary steps in that code... And to answer your question, yes, you should check for an operand. Here is how I would write that method with a check:
NSString *text = [display text];
int length = [text length];
unichar c = [text characterAtIndex:length];
NSCharacterSet *digits = [NSCharacterSet decimalCharacterSet];
if ([digits characterIsMember:c] || c == '.') {
NSString *temp = [[display text] substringToIndex:length-1];
[display setText:temp];
}
I'm also going through the fall 2011 class on iTunes U.
The walk through gives us an instance variable userIsInTheMiddleOfEnteringANumber so I just checked to see if that is YES.
- (IBAction)backspacePressed {
if (self.userIsInTheMiddleOfEnteringANumber) {
if ([self.display.text length] > 1) {
self.display.text = [self.display.text substringToIndex:[self.display.text length] - 1];
} else {
self.display.text = #"0";
self.userIsInTheMiddleOfEnteringANumber = NO;
}
}
}
I used the approach taken by Joe_Schmoe, which is straightforward. (just remove characters in the dispaly until you reach the end).
If the user continues pressing 'Clear Error', I removed an item from the stack as well.
I have just started on the course myself, this post is quite old now but my solution might help others, food for thought if nothing else:
- (IBAction)deletePressed:(id)sender
{
NSString *displayText = [display text];
int length = [displayText length];
if (length != 1) {
NSString *newDisplayText = [displayText substringToIndex:length-1];
[display setText:[NSString stringWithFormat:#"%#",newDisplayText]];
} else {
userIsInTheMiddleOfEnteringANumber = NO;
NSString *newDisplayText = #"0";
[display setText:[NSString stringWithFormat:#"%#",newDisplayText]];
}
}

How to randomize two UITextField variables?

I have two textFields where the user types into some words.
Then, when pressing a button, i want the words to randomize and then the user displays the randomized result.
I have this code:
-(IBAction) randomInp{
NSString *first = firstField.text;
NSString *second = secondField.text;
NSString *result = //here it should randomize the words
//Display randomized word
textview.text = //should display result
}
where firstField and secondField are respectively the first and the second UITextFields. Then i don't know how to proceed!
I was thinking of set a switch condition. If it's 0 then returns *first, if it's 1 then returns *second. Am i right?
Any help appreciated
EDIT
Solved!
If anyone needs:
-(IBAction) randomInp{
NSString *first = firstField.text;
NSString *second = secondField.text;
int text = rand() % 2;
switch (text) {
case 0:
textview.text = first;
break;
case 1:
textview.text = second;
break;
default:
break;
}
}
EDIT 2
The answer that SSteve gave works great, too! For anyone who needs:
NSString *result = random() & 1 ? first : second;
To choose between two values you can use random() and check the value of a bit:
NSString *result = random() & 1 ? first : second;
Put a call to srandomdev() somewhere in your initialization code to avoid having the same sequence of values every time your program runs. You may also need #include <stdlib.h>

Objective C - Random XIB pick

I have already posted another question about this, but no one seemed to know how to do this.
I want my app to pick a random XIB file for me, but dont use the ones that have already been randomly picked.
So heres what i have set up as of right now, it seems to work, but i have to keep pressing the button over and over until it finds one that hasnt be used.
-(IBAction)continueAction:(id)sender{
random = arc4random() % 2;
if (random == 0 && usedQ2 == 0) {
Question_2 *Q2 = [[Question_2 alloc] initWithNibName:#"Question 2" bundle:nil];
Q2.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:Q2 animated:YES];
[Q2 release];
}
else if (random == 1 && usedQ3 == 0) {
Question_3 *Q3 = [[Question_3 alloc] initWithNibName:#"Question 3" bundle:nil];
Q3.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:Q3 animated:YES];
[Q3 release];
}
}
So as you can see i have it pick from a random number, and from their find the one that it matches.
Then you can see i have another part of my if statement that is checking to make sure it hasn't been used before.
each NIB file has its own usedQ(whatever Q it is), and when that Nib file is loaded it puts that usedQ as 1.
I think i could get by doing this, but in order to get rid of the constant button pushing, i will have to put loads of else statements with more else statements in them.
I have also tried running the
random = arc4random() % 2;
in a while statement and a for statement, i hoped that it would keep looking for a number until one that hasn't be used was found with no luck.
Any help? thanks!
Why don't you make a mutable array
and populate it with the names of all
your nibs.
Then read the count of the array and
generate a random number in that
range.
Extract the nib name at that index
and remove it from the array.
repeat steps 2-3.
//Setup your list at an appropriate place
NSMutableArray *nibs
= [[NSMutableArray alloc] initWithObjects: #"One Nib", #"Another
Nib", #"Last Nib", nil];
self.unusedNibs = nibs; //This should be a property you declare in
your header.
[nibs release];
-(IBAction)continueAction:(id)sender{
int random = arc4random() % [self.unusedNibs count];
NSString
*nibName = [self.unusedNibs objectAtIndex: random];
[self.unusedNibs removeObjectAtIndex:
random];
//Load nib here.
}