Eyes, JAPAN Blog > Practice of KIWI for iOS Development

Practice of KIWI for iOS Development

will

この記事は1年以上前に書かれたもので、内容が古い可能性がありますのでご注意ください。

After using the kiwi for testing in the project. It is nice tool for testing on iOS.

To integrate it in the iOS project. There is document from this repository in the github. click to check

Here is an example of how to use it for testing UI including database access.

The Structure of Test Case Class is as following image

Untitled

1. import the necessary headers;
2. extension of class to be tested;
3. KWSpec class and example group declaration;
4. block to create necessary UI components of controller;
5. group of context;
6. the blocks to do set up and tear down for every example;
7. context of use case, consist of examples

Class Extension

Extend the interface of class can enable the test code to access private attributes or methods. In the test class,can be write as following:

@interface MgtMenuItemEditingViewController (TestMgtMenuItemEditingViewController)

@property(nonatomic, weak)IBOutlet UITextField                  *itemNameENTextField;
@property(nonatomic, weak)IBOutlet UITextField                  *itemNameJATextField;
@property(nonatomic, weak)IBOutlet UITextField                  *priceTextField;
@property(nonatomic, weak)IBOutlet UIButton                     *startTimeButton;
@property(nonatomic, weak)IBOutlet UIButton                     *endTimeButton;
@property(nonatomic, weak)IBOutlet UIImageView                  *imageView;
@property(nonatomic, weak)IBOutlet UITextView                   *detailDescription;
@property(nonatomic, weak)IBOutlet UISegmentedControl           *enableOrDisableSegmentedControl;
@property(nonatomic, weak)IBOutlet UITableView                  *categoryTableView;
@property(nonatomic, weak)IBOutlet UITableView                  *optionTableView;
@property(nonatomic, weak)IBOutlet UIButton                     *imagePickButton;
@property(nonatomic, weak)IBOutlet UIScrollView                 *scrollView;
@property(nonatomic, retain)ItemCategory                        *selectedItemCategory;//selected category
@property(nonatomic, retain)NSMutableArray                      *selectedOptionArray; //selected option categories
@property(nonatomic, retain)UIImage                             *selectedImage;
@property(nonatomic, retain)NSArray                             *itemCategories;//all the item categories from DB
@property(nonatomic, retain)NSArray                             *avaliableOptions;//all the option categories from DB
@property(nonatomic, retain)UIPopoverController                 *imagePopoverController;
@property(nonatomic, assign)NSInteger                           currentActiveTextFiledTag;
@property(nonatomic, retain)UIPopoverController                 *startTimePickerPopover;
@property(nonatomic, retain)UIPopoverController                 *endTimePickerPopover;

-(IBAction)pushSelectImage:(id)sender;
-(IBAction)pushSave:(id)sender;
-(IBAction)dismissKeyboard:(id)sender;

@end

Crate block of view controller
We create the necessary UI components like story board do.

MgtMenuItemEditingViewController * (^createMenuItemVC)(NSArray *stringArray)=
^MgtMenuItemEditingViewController *(NSArray *stringArray){

    MgtMenuItemEditingViewController *menuItemEditingVC = [[MgtMenuItemEditingViewController alloc] init];

//create UI Components
    UITextField          *itemNameENTextField               = [[UITextField alloc] init];
   NSArray *itemArray = [NSArray arrayWithObjects: @"有効", @"無効", nil];
    UISegmentedControl   *enableOrDisableSegmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
    .....
 // set the text of relative UI components
    if(stringArray){
 itemNameJATextField.text =    [stringArray objectAtIndex:0];
        ...
    }

 //add UI components to view controller ‘s view
    [menuItemEditingVC.view addSubview:itemNameENTextField];
    ...
    menuItemEditingVC.itemNameENTextField     = itemNameENTextField;
    ....

//set the necessary delegate
    [categoryTableView setDelegate:menuItemEditingVC];
    [categoryTableView setDataSource:menuItemEditingVC];
    [optionTableView setDelegate:menuItemEditingVC];
    [optionTableView setDataSource:menuItemEditingVC];
    [enableOrDisableSegmentedControl setSelectedSegmentIndex:0];
    return menuItemEditingVC;
};

Context block

A context is a use case, context is consist of several example block, call “it”.

    //Test show the content of menu item correct on the relative UI component
    context(@"After load the view, the relative UI component should be initialized correctly",^{
        
        __block NSManagedObjectContext *managedObjectContect;
        
        beforeEach(^{
            managedObjectContect = [NSManagedObjectContext MR_defaultContext];
        });
        
        it(@"if the menut item is just created, the UI component should be initilaized correctly", ^{  
//block of example            
        });
        
        it(@"if the menut item is not nil, the UI component should be initilaized correctly", ^{  
//block of example                        
        });
        
        
    });

Example Block



        it(@"if the menut item is just created, the UI component should be initilaized correctly", ^{
            
            MgtMenuItemEditingViewController *menuItemEditingViewController = createMenuItemVC(nil);
            
            NSArray *categoryArrayEN = [[NSArray alloc] initWithObjects:@"Espresso",@"Single Origin", @"Non-Cofee", @"All Time Plate", @"Lunch", @"Sweets", nil];
            NSArray *categoryArrayJA = [[NSArray alloc] initWithObjects:@"エスプレッソ",@"シングル オリジン", @"コーヒー以外", @"オールタイムプレート", @"ランチ", @"スイーツ", nil];
            NSArray *optionArray = [[NSArray alloc] initWithObjects:@"淹れ方",@"ショット", @"ミルク", @"トッピング", nil];
            //create the necessary categories and options
            for(int i = 0; i < categoryArrayEN.count; i++){
                
                NSString *categoryEN = [categoryArrayEN objectAtIndex:i];
                NSString *categoryJA = [categoryArrayJA objectAtIndex:i];
                ItemCategory *itemCategory = [ItemCategory MR_createInContext:managedObjectContect];
                itemCategory.categoryName_EN = categoryEN;
                itemCategory.categoryName_JA = categoryJA;
                itemCategory.rowNo = [[NSNumber alloc] initWithInt:i];
                
            }            
            for(int j = 0; j < optionArray.count; j++){
                NSString *optionName = [optionArray objectAtIndex:j];
                OptionCategory *optionCategory = [OptionCategory MR_createInContext:managedObjectContect];
                optionCategory.optionName_JA = optionName;
                optionCategory.rowNo = [[NSNumber alloc] initWithInt:j];
                
            }
            [managedObjectContect MR_saveOnlySelfAndWait];

            
            menuItemEditingViewController.menuItem = nil;
            
          [menuItemEditingViewController viewDidLoad];
            
//write all the possible expectations  
            [menuItemEditingViewController.itemNameENTextField.text shouldBeNil];
            [menuItemEditingViewController.itemNameJATextField.text shouldBeNil];
            [menuItemEditingViewController.priceTextField.text shouldBeNil];
            [[menuItemEditingViewController.startTimeButton titleForState:UIControlStateNormal] shouldBeNil];
            [[menuItemEditingViewController.endTimeButton titleForState:UIControlStateNormal] shouldBeNil];
            [menuItemEditingViewController.imageView.image shouldBeNil];
            [[menuItemEditingViewController.detailDescription.text should] equal:@""];
            
            //the default value of category will be the first category in the list
            [[theValue([[menuItemEditingViewController.categoryTableView indexPathForSelectedRow] row]) should] equal:theValue(0)];

            [[theValue([menuItemEditingViewController.enableOrDisableSegmentedControl selectedSegmentIndex]) should] equal:theValue(0)];
            
        });

Comments are closed.