rubymotion3 android,RubyMotion 指南:测试

翻译:@shiweifu

本文链接:http://segmentfault.com/blog/shiweifu

原文链接:http://rubymotion-tutorial.com/8-testing/

目标读者:["想了解RubyMotion开发模式", "想学习RubyMotion", "对移动端测试感兴趣"]

翻译者按:测试是移动开发的一个痛点。这篇文章讲述了使用RubyMotion如何进行有效的测试,可以看出相对于原生开发环境的测试,简化很多。这部分也是RubyMoiton的一大特色。

除了语法不同,你可能觉得 RubyMotion 不过是提供了一条使用 Ruby 语法来编写 Cocoa 程序的方式。和使用 Objective-C 来实现同样的功能相比,并无特殊之处。本章将介绍 RubyMotion 中独有的特性。

自动化测试是屌炸天的事儿。屌在哪?它能使你的程序更加健壮,通过一些测试代码,能让你及时发现问题所在,是不是很棒?

是的,大家都认为测试是个好东西,但事实上大多数工程师并不能坚持写测试。它不能让你有足够的成就感,不是能和其他人吹嘘的牛逼特性或者性能提升。但它是一种保障,特别是项目经常改变,它能让你知道你的代码究竟可不可用。

接下来我们将了解 RubyMotion 中的测试,简单编写,覆盖度高。

在 Ruby 社区,大家都很重视测试,Ruby 的测试相对 iOS App,也相对简洁。如果要在iOS 中实现自动化测试,往往需要借助第三方库或者使用JavaScript。RubyMotion 的测试库要好用的多。

到底有多屌?

Unit Testing

使用 motion create Tests 命令新建一个项目然后cd进去。我们讨论里面的spec文件夹。

这个文件夹里有一个名为./spec/main_spec.rb的文件,这是创建项目的时候自动生成的。在 RubyMotion 的测试工作的时候,它会加载这个文件夹里面的*.rb文件。我们来看下这个文件的内容:

describe "Application 'Tests'" do

before do

@app = UIApplication.sharedApplication

end

it "has one window" do

@app.windows.size.should == 1

end

end

可以看到一个简单的表达式:@app.windows.size.should == 1,它的意思看起来是如果.size不为1,就测试失败。

.should 支持以下的判断类型:

@app.nil?.should == false

[1,2,3].should.not == [1,2,3,4]

@model.id.should == example_id

describe 和 it 组成了一个用来实现测试的结构。在上面的这个describe结构中,传达了两个意思:"[Test that] Application",被测试对象有一Window。一个describe结构中可以包含多个it,it中又可以包含多个测试断言。你如果喜欢的话,也可以写多个describe。

每一个将被测试的内容都会先执行before中的内容。应该把一些初始化的代码丢到这里。

接下来在终端中,运行rake spec,看看测试的结果。

1.png

还是挂了……提示说没有找到window。让我们在AppDelegate中修复:

class AppDelegate

def application(application, didFinishLaunchingWithOptions:launchOptions)

@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.applicationFrame)

@window.makeKeyAndVisible

true

end

end

再执行一次rake spec,这次正确了:

2.png

咦,似乎已经通过自动化测试解决了一个Bug,但愿是真的解决了吧。

我们已经看到了如何去检查一个对象的属性,这很有用但还不够。有时候我们会触发事件,比如我们敲击了一个按钮,它调用了一个内部方法,这种情况下,我们要测试需要去手动调用这个方法,然后进行测试……事实上有更好的做法。

Funcational Testing

RubyMotion 对 Funcational Testing 有着很好的支持,比如你想测试触发 UI 事件,如Tap、Swipe 然后检查它的结果,你不用去button.callback.call,你可以用等效的方法:tap button,测试用例很整洁,对不对?

Funcational Testing虽然屌屌的,但它的局限是它只能测试一个UIViewController。所以像push和pop这种就无能为力了。需要注意。

要接着跑通这个例子,我们需要一个UIViewController的子类,创建./app/ButtonController.rb,然后增加一个按钮和回调事件。代码如下:

class ButtonController < UIViewController

def viewDidLoad

super

@button = UIButton.buttonWithType(UIButtonTypeRoundedRect)

@button.setTitle("Test me title!", forState:UIControlStateNormal)

@button.accessibilityLabel = "Test me!"

@button.sizeToFit

@button.frame = CGRect.new([10, 70], @button.frame.size)

self.view.addSubview(@button)

@button.addTarget(self, action:'tapped', forControlEvents:UIControlEventTouchUpInside)

end

def tapped

p "I'm tapped!"

@was_tapped = true

end

end

标准的代码,除了accessibilityLabel。这是每个View都包含的一个String类型属性。当使用VoiceOver功能的时候,系统依赖这个属性(所以别随便设置这个属性的值)。为啥我们会提到这一点?因为 RubyMotion 的Funcational Testing就依赖这个属性。所以确保要测试的View已经设置好这个属性。

最后,我们把Controller和AppDelegate关联起来:

def application(application, didFinishLaunchingWithOptions:launchOptions)

@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.applicationFrame)

@window.makeKeyAndVisible

@view_controller = ButtonController.alloc.initWithNibName(nil, bundle:nil)

@window.rootViewController = @view_controller

true

end

你可以使用rake执行一下,看看在你触发按钮事件的时候终端有没有输出I'm tapped!。接下来我们写测试代码,看看变量是否真的被赋值。

在main_spec.rb,添加describe块及代码:

describe "button controller" do

tests ButtonController

it "changes instance variable when button is tapped" do

tap 'Test me!'

controller.instance_variable_get("@was_tapped").should == true

end

end

让我们来看看有啥新东西。

tests 连接我们的describe,指定UIViewController。它的行为很清晰:将要测试的UIViewController放在了一个新的UIWindow中。我们能使用self.window和self.controller访问其。这样做也确保了被测试的Controller不会被干扰。

tap可以替换成flick、drag、pinch_close、pinch_open和rotate对应相应的行为。查看RubyMotion's full documentation具体的细节。

rake spec,它已经能正常工作啦:

2 specifications (2 requirements), 0 failures, 0 errors

总结

我们看到了在RubyMotion中编写测试是多么的简单。如果你之前因为繁琐不写测试,现在没理由懒惰了。

我们学到了啥?

RubyMotion加载测试用例从./spec目录。

测试用例包含在describe和it中,后面跟随着标签,用来标识和组织。

使用 .should 进行断言。例:greeting.should == "hello"。

UIViewControllers可以进行funcational。 tests,可以模拟一些像tap、pinch触发事件。在你的describe代码块中,使用tests 去使用这些特性。

tap 是访问View的accessibilityLabel属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值