qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

UTF-8使用纯真IP数据库乱码问题

最近手头在写一个根据IP地址返回省份地区的代码,发现在使用纯真ip数据库的时候出现乱码,最后发现纯真数据库是居于GBK编码的,而我的整个工程编码都是采用的UTF-8编码,两个走到一起肯定会出现乱码,所以只能改写纯真读取ip的类
<%
'得到访问者IP
public Function getip()
Dim strIPAddr
If Request.ServerVariables("HTTP_X_FORWARDED_FOR") = "" OR InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), "unknown") > 0 Then
strIPAddr = Request.ServerVariables("REMOTE_ADDR")
ElseIf InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ",") > 0 Then
strIPAddr = Mid(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), 1, InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ",")-1)
actforip=Request.ServerVariables("REMOTE_ADDR")
ElseIf InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ";") > 0 Then
strIPAddr = Mid(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), 1, InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ";")-1)
actforip=Request.ServerVariables("REMOTE_ADDR")
Else
strIPAddr = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
actforip=Request.ServerVariables("REMOTE_ADDR")
End If
getip = Trim(Mid(strIPAddr, 1, 30))
End Function
' ============================================
' 返回IP地区信息
' ============================================
Function Look_Ip(IP)
Dim Wry, IPType, QQWryVersion, IpCounter
' 设置类对象
Set Wry = New TQQWry
' 开始搜索,并返回搜索结果
' 您可以根据 QQWry(IP) 返回值来判断该IP地址在数据库中是否存在,如果不存在可以执行其他的一些操作
' 比如您自建一个数据库作为追捕等,这里我就不详细说明了
IPType = Wry.QQWry(IP)
' Country:国家地区字段
' LocalStr:省市及其他信息字段
Look_Ip = Wry.Country & " " & Wry.LocalStr
End Function
' ============================================
' 返回QQWry信息
' ============================================
Function WryInfo()
Dim Wry, IPType, QQWry(1)
' 设置类对象
Set Wry = New TQQWry
IPType = Wry.QQWry("255.255.255.255")
' 读取数据库版本信息
QQWry(0) = Wry.Country & " " & Wry.LocalStr
' 读取数据库IP地址数目
QQWry(1) = Wry.RecordCount + 1
WryInfo = QQWry
End Function
' ============================================
' IP物理定位搜索类
' ============================================
Class TQQWry
' ============================================
' 变量声名
' ============================================
Dim Country, LocalStr, Buf, OffSet
Private StartIP, EndIP, CountryFlag
Public QQWryFile
Public FirstStartIP, LastStartIP, RecordCount
Private Stream, EndIPOff
' ============================================
' 类模块初始化
' ============================================
Private Sub Class_Initialize
Country = ""
LocalStr = ""
StartIP = 0
EndIP = 0
CountryFlag = 0
FirstStartIP = 0
LastStartIP = 0
EndIPOff = 0
QQWryFile = Server.MapPath("/yxgame/date/qqwry.dat") 'QQ IP库路径,要转换成物理路径
End Sub
' ============================================
' IP地址转换成整数 ip
' ============================================
Function IPToInt(IP)
If Instr(IP,":")>0 Then IP="127.0.0.1" '当IP地址是::1这样的地址时返回本机地址
Dim IPArray, i
IPArray = Split(IP, ".", -1)
FOr i = 0 to 3
If Not IsNumeric(IPArray(i)) Then IPArray(i) = 0
If CInt(IPArray(i)) < 0 Then IPArray(i) = Abs(CInt(IPArray(i)))
If CInt(IPArray(i)) > 255 Then IPArray(i) = 255
Next
IPToInt = (CInt(IPArray(0))*256*256*256) + (CInt(IPArray(1))*256*256) + (CInt(IPArray(2))*256) + CInt(IPArray(3))
End Function
' ============================================
' 整数逆转IP地址
' ============================================
Function IntToIP(IntValue)
p4 = IntValue - Fix(IntValue/256)*256
IntValue = (IntValue-p4)/256
p3 = IntValue - Fix(IntValue/256)*256
IntValue = (IntValue-p3)/256
p2 = IntValue - Fix(IntValue/256)*256
IntValue = (IntValue - p2)/256
p1 = IntValue
IntToIP = Cstr(p1) & "." & Cstr(p2) & "." & Cstr(p3) & "." & Cstr(p4)
End Function
' ============================================
' 获取开始IP位置
' ============================================
Private Function GetStartIP(RecNo)
OffSet = FirstStartIP + RecNo * 7
Stream.Position = OffSet
Buf = Stream.Read(7)
EndIPOff = AscB(MidB(Buf, 5, 1)) + (AscB(MidB(Buf, 6, 1))*256) + (AscB(MidB(Buf, 7, 1))*256*256)
StartIP = AscB(MidB(Buf, 1, 1)) + (AscB(MidB(Buf, 2, 1))*256) + (AscB(MidB(Buf, 3, 1))*256*256) + (AscB(MidB(Buf, 4, 1))*256*256*256)
GetStartIP = StartIP
End Function
' ============================================
' 获取结束IP位置
' ============================================
Private Function GetEndIP()
Stream.Position = EndIPOff
Buf = Stream.Read(5)
EndIP = AscB(MidB(Buf, 1, 1)) + (AscB(MidB(Buf, 2, 1))*256) + (AscB(MidB(Buf, 3, 1))*256*256) + (AscB(MidB(Buf, 4, 1))*256*256*256)
CountryFlag = AscB(MidB(Buf, 5, 1))
GetEndIP = EndIP
End Function
' ============================================
' 获取地域信息,包含国家和和省市
' ============================================
Private Sub GetCountry(IP)
If (CountryFlag = 1 or CountryFlag = 2) Then
Country = GetFlagStr(EndIPOff + 4)
If CountryFlag = 1 Then
LocalStr = GetFlagStr(Stream.Position)
' 以下用来获取数据库版本信息
If IP >= IPToInt("255.255.255.0") And IP <= IPToInt("255.255.255.255") Then
LocalStr = GetFlagStr(EndIPOff + 21)
Country = GetFlagStr(EndIPOff + 12)
End If
Else
LocalStr = GetFlagStr(EndIPOff + 8)
End If
Else
Country = GetFlagStr(EndIPOff + 4)
LocalStr = GetFlagStr(Stream.Position)
End If
' 过滤数据库中的无用信息
Country = Trim(Country)
LocalStr = Trim(LocalStr)
If InStr(Country, "CZ88.NET") Then Country = "本地/局域网"
If InStr(LocalStr, "CZ88.NET") Then LocalStr = "本地/局域网"
End Sub
' ============================================
' 获取IP地址标识符
' ============================================
Private Function GetFlagStr(OffSet)
Dim Flag
Flag = 0
Do While (True)
Stream.Position = OffSet
Flag = AscB(Stream.Read(1))
If(Flag = 1 or Flag = 2 ) Then
Buf = Stream.Read(3)
If (Flag = 2 ) Then
CountryFlag = 2
EndIPOff = OffSet - 4
End If
OffSet = AscB(MidB(Buf, 1, 1)) + (AscB(MidB(Buf, 2, 1))*256) + (AscB(MidB(Buf, 3, 1))*256*256)
Else
Exit Do
End If
Loop
If (OffSet < 12 ) Then
GetFlagStr = ""
Else
Stream.Position = OffSet
GetFlagStr = GetStr()
End If
End Function
' ============================================这里获取代码最关键了
' 获取字串信息 (www.viming.com)
'-----utf-8-----------
Private Function GetStr()
dim c
getstr = ""
dim objstream
set objstream = server.createobject("adodb.stream")
objstream.type = 1
objstream.mode =3
objstream.open
c = stream.read(1)
do while (ascb(c)<>0 and not stream.eos)
objstream.write c
c = stream.read(1)
loop
objstream.position = 0
objstream.type = 2
objstream.charset = "gb2312"
getstr = objstream.readtext
objstream.close
set objstream = nothing
End Function
' ============================================
' 核心函数,执行IP搜索
' ============================================
Public Function QQWry(DotIP)
Dim IP, nRet
Dim RangB, RangE, RecNo
IP = IPToInt (DotIP)
Set Stream = CreateObject("ADodb.Stream")
Stream.Mode = 3
Stream.Type = 1
Stream.Open
Stream.LoadFromFile QQWryFile
Stream.Position = 0
Buf = Stream.Read(8)
FirstStartIP = AscB(MidB(Buf, 1, 1)) + (AscB(MidB(Buf, 2, 1))*256) + (AscB(MidB(Buf, 3, 1))*256*256) + (AscB(MidB(Buf, 4, 1))*256*256*256)
LastStartIP = AscB(MidB(Buf, 5, 1)) + (AscB(MidB(Buf, 6, 1))*256) + (AscB(MidB(Buf, 7, 1))*256*256) + (AscB(MidB(Buf, 8, 1))*256*256*256)
RecordCount = Int((LastStartIP - FirstStartIP)/7)
' 在数据库中找不到任何IP地址
If (RecordCount <= 1) Then
Country = "未知"
QQWry = 2
Exit Function
End If
RangB = 0
RangE = RecordCount
Do While (RangB < (RangE - 1))
RecNo = Int((RangB + RangE)/2)
Call GetStartIP (RecNo)
If (IP = StartIP) Then
RangB = RecNo
Exit Do
End If
If (IP > StartIP) Then
RangB = RecNo
Else
RangE = RecNo
End If
Loop
Call GetStartIP(RangB)
Call GetEndIP()
If (StartIP <= IP) And ( EndIP >= IP) Then
' 没有找到
nRet = 0
Else
' 正常
nRet = 3
End If
Call GetCountry(IP)
QQWry = nRet
End Function
' ============================================
' 类终结
' ============================================
Private Sub Class_Terminate
On ErrOr Resume Next
Stream.Close
If Err Then Err.Clear
Set Stream = Nothing
End Sub
End Class
%>
  最后就简单了,到需要用到显示的地方只需调用 look_ip()这个函数就可以了,哈哈。



posted @ 2013-10-16 10:50 顺其自然EVO 阅读(708) | 评论 (0)编辑 收藏

对于linux操作系统的认识和了解

 这两天被问道对于linux操作系统的认识了解,当时自己只说了它的开源性和多平台移植性,而且也说得不够清楚,所以特来补充额外的一些。
  linux是一种自由和开放源码的类unix操作系统,是一个基于POSIX和UNIX的多用户,多任务,支持多线程和多CPU的操作系统
  其主要从以下几个方面吧,个人觉得
  (1)linux的基本思想:一切皆文件。
  (2)linux完全免费的特性,因为开源,用户可以任意修改其源码。因为这一点,世界上无数的程序员可以参与尽量,使得linux不断的发展壮大。
  (3)多用户和多任务性:
  (4)Linux支持多种平台,如X86,ARM等多种处理器平台。此外linux还是一种嵌入式操作系统。
  linux下的常用命令:
  date:显示系统时间
  file 文件名:确定指定的文件类型
  ls:列出目录文件
  shutdown:关机命令
  cp:复制
  mkdir:创建目录,rmdir:删除目录
  cd:切换目录
  pwd:显示当前目录
  还有等等一些,就不一一列举了。

posted @ 2013-10-16 10:41 顺其自然EVO 阅读(368) | 评论 (0)编辑 收藏

Selenium2.0功能测试之Close browser

关闭浏览器是每条Case执行完成或者测试进行结束必要的操作,Selenium提供了两种关闭浏览器的方法:
  driver.close() ; 作用为关闭当前的浏览器窗口。
  driver.quit(); 作用为不仅关闭了当前的浏览器窗口还彻底的退出WedDriver,释放了Driver与Server之间的链接。一句话总结就是:quit是更加彻底的close,quit会更好的释放资源。所以quit方法比较适合我这种强迫症患者,那么到底用哪种方式关闭浏览器就以你自己的病症而异了。
package org.coderinfo.demo;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class CloseBrowser {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("http://www.google.com.hk");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//      driver.close();  仅关闭当前浏览器窗口
driver.quit();  //彻底退出WebDriver
}
}
相关文章
Selenium2.0功能测试之设置浏览器大小
Selenium2.0功能测试之Start browsers

posted @ 2013-10-15 11:30 顺其自然EVO 阅读(266) | 评论 (0)编辑 收藏

使用 JUnit 进行 Java 代码的单元测试

  下载安装 JUnit 的相关文件
  首先我们需要先下载相应的 JUnit 相关的 JAR 包,下载的过程可以去 JUnit 的官方网站,也可以直接通过 Maven 资源仓库来完成,我这里直接通过开源中国社区在国内的Maven 镜像下载了 JUnit-4.8.2.jar 的版本,如下图所示:
  直接搜索关键字"junit"即可,我们可以从搜索结果中找到红色方框1中的对应项,选中之后就会在左下方列出目前可以获得的 junit  的所有版本,这里我选择了 4.8.2 的版本(红色方框2),然后点击右侧的 Download 按钮即可下载这個 JAR 包,不过依我在实践中的经验,最好同时下载对应版本的 javadoc 和 source 两個包,前者是文档,后者是对应的源代码,然后将它们直接引入到我们的 eclipse 的工程中即可。我这里创建了壹個普通的 Java Project ,并给它取名 junit-study ,导入 JAR 包之后目前的样子如下图所示:
  使用简单的 @Test 注解实现我们的测试方法的编写和执行
  准备工作做好之后,接下来我们就可以开始尝试编写壹個简单的测试代码了。首先,我们编写了壹個 Calculator 类,并提供五個方法分别完成加减乘除以及求平方的运算。代码如下:
package net.oschina.bairrfhoinn.main;
public class Calculator {
public void add(int n){
result += n;
}
public void substract(int n){
result -= n;
}
public void multiply(int n){
result *= n;
}
public void divide(int n){
result /= n;
}
public void square(int n){
result = n * n;
}
public int getReuslt(){
return result;
}
public void clear(){
result = 0;
}
private static int result;
}
  在测试类中用到了JUnit4框架,自然要把相应地Package包含进来。最主要地一个Package就是org.junit.*。把它包含进来之后,绝大部分功能就有了。还有一句话也非常地重要“import static org.junit.Assert.*;”,我们在测试的时候使用的壹系列assertEquals()方法就来自这个包。大家注意壹下,这是壹個静态包含(static),是JDK5中新增添的壹個功能。也就是说,assertEquals是Assert类中的壹系列的静态方法,壹般的使用方式是Assert. assertEquals(),但是使用了静态包含后,前面的类名就可以省略了,使用起来更加的方便。
  另外要注意的是,我们的测试类是壹個独立的类,没有任何父类。测试类的名字也可以任意命名,没有任何局限性。所以我们不能通过类的声明来判断它是不是一个测试类,它与普通类的区别在于它内部的方法的声明,我们接着会讲到。在测试类中,并不是每壹個方法都是用于测试的,所以我们必须使用“注解”来明确表明哪些是测试方法。“注解”也是JDK5的壹個新特性,用在此处非常恰当。我们可以看到,在某些方法的前有@Before、@Test、@Ignore等字样,这些就是注解,以壹個“@”作为开头。这些注解都是JUnit4自定义的,熟练掌握这些注解的含义,对于编写恰当的测试类非常重要。
 接下来我们创建壹個测试类 CalculatorTest.java,代码如下:
package net.oschina.bairrfhoinn.test;
import static org.junit.Assert.*;
import org.junit.Test;
import net.oschina.bairrfhoinn.main.Calculator;
public class CalculatorTest {
private static Calculator calculator = new Calculator();
@Test
public void testAdd(){
calculator.add(7);
calculator.add(8);
assertEquals(15, calculator.getReuslt());
}
}
  首先,我们要在方法的前面使用@Test标注,以表明这是壹個测试方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。如果违反这些规定,会在运行时抛出壹個异常。至于方法内该写些什么,那就要看你需要测试些什么了。比如上述代码中,我们想测试壹下add()方法的功能是否正确,就在测试方法中调用几次add函数,初始值为0,先加7,再加8,我们期待的结果应该是15。如果最终实际结果也是15,则说明add()方法是正确的,反之说明它是错的。assertEquals(15, calculator.getResult());就是用来判断期待结果和实际结果是否相等,其中第壹個参数填写期待结果,第二個参数填写实际结果,也就是通过计算得到的结果。这样写好之后,JUnit 会自动进行测试并把测试结果反馈给用户。
  如果想运行它,可以在 eclipse 的资源管理器中选择该类文件,然后点击右键,选择 Run As->JUnit Test 即可看到运行结果如下图所示:
  使用@Test 的属性 Ignore 指定测试时跳过这個方法
  如果你在写程序前做了很好的规划,那么哪些方法是什么功能都应该实现并且确定下来。因此,即使该方法尚未完成,他的具体功能也是确定的,这也就意味着你可以为他编写测试用例。但是,如果你已经把该方法的测试用例写完,但该方法尚未完成,那么测试的时候无疑是“失败”。这种失败和真正的失败是有区别的,因此 JUnit 提供了壹种方法来区别他们,那就是在这种测试函数的前面加上 @Ignore 标注,这个标注的含义就是“某些方法尚未完成,暂不参与此次测试”。这样的话测试结果就会提示你有几個测试被忽略,而不是失败。壹旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。
  比如说上面的测试类 Calculator.java 中,假设我们的 Calculator 类的 multiply() 方法没有实现,我们可以在测试类 CalculatorTest 中先写如下测试代码:
package net.oschina.bairrfhoinn.test;
import static org.junit.Assert.*;
import org.junit.Ignore;
import org.junit.Test;
import net.oschina.bairrfhoinn.main.Calculator;
public class CalculatorTest {
private static Calculator calculator = new Calculator();
... //此处代码省略
@Ignore("method square() not implemented, please test this later...")
@Test
public void testSquare(){
calculator.square(3);
assertEquals(9, calculator.getReuslt());
}
}
  我们再运行壹次测试,会看到如下结果,从图中可以很明显的看出,方法testSquare() 上的 @Ignore 注解已经生效了,运行时直接跳过了它,而方法testAdd()仍然正常的运行并通过了测试。
  使用注解 @Before 和 @After 来完成前置工作和后置工作
  前置工作通常是指我们的测试方法在运行之前需要做的壹些准备工作,如数据库的连接、文件的加载、输入数据的准备等需要在运行测试方法之前做的事情,都属于前置工作;类似的,后置工作则是指测试方法在运行之后的壹些要做的事情,如释放数据库连接、输入输出流的关闭等;比如我们上面的测试,由于只声明了壹個 Calculator 对象,他的初始值是0,但是测试完加法操作后,他的值就不是0了;接下来测试减法操作,就必然要考虑上次加法操作的结果。这绝对是壹個很糟糕的设计!我们非常希望每壹個测试方法都是独立的,相互之间没有任何耦合度。因此,我们就很有必要在执行每壹個测试方法之前,对Calculator对象进行壹個“复原”操作,以消除其他测试造成的影响。因此,“在任何壹個测试方法执行之前必须执行的代码”就是壹個前置工作,我们用注解 @Before 来标注它,如下例子所示:
package net.oschina.bairrfhoinn.test;
...
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
public class CalculatorTest {
...//这里省略部分代码
@Before
public void setUp() throws Exception {
calculator.clear();
}
@After
public void tearDown() throws Exception {
System.out.println("will do sth here...");
}
...//这里省略部分代码
}
 另外要说的是,注解 @Before 是定义在 org.junit.Before 这個类中的,因此使用时需要将其引入我们的代码中。这样做了之后,每次我们运行测试方法时,JUnit 都会先运行 setUp() 方法将 result 的值清零。不过要注意的是,这里不再需要 @Test 注解,因为这并不是壹個 test,只是壹個前置工作。同理,如果“在任何测试执行之后需要进行的收尾工作,我们应该使用 @After 来标注,方法与它类似。由于本例比较简单,不需要用到此功能,所以我们只是简单了给它添加了壹個 tearDown() 方法并在收尾时打印壹句话到控制台,并且使用 @After 来注解这個方法。
  使用@BeforeClass 和 @AfterClass 来完成只需要执行壹次的前置工作和后置工作
  上面我们提到了两個注解 @Before 和 @After ,我们来看看他们是否适合完成如下功能:有壹個类负责对大文件(超过500 MB)进行读写,他的每壹個方法都是对文件进行操作。换句话说,在调用每壹個方法之前,我们都要打开壹個大文件并读入文件内容,这绝对是壹個非常耗费时的操作。如果我们使用 @Before 和 @After ,那么每次测试都要读取壹次文件,效率及其低下。所以我们希望的是,在所有测试壹开始读壹次文件,所有测试结束之后释放文件,而不是每次测试都读文件。JUnit的作者显然也考虑到了这个问题,它给出了@BeforeClass 和 @AfterClass 两個注解来帮我们实现这个功能。从名字上就可以看出,用这两個注解标注的函数,只在测试用例初始化时执行 @BeforeClass 方法,当所有测试执行完毕之后,执行 @AfterClass 进行收尾工作。在这里要注意壹下,每個测试类只能有壹個方法被标注为 @BeforeClass 或 @AfterClass,而且该方法必须是 public static 类型的。
  使用@Test 的属性 timeout 来完成限时测试,以检测代码中的死循环
  现在假设我们的 Calculator 类中的 square() 方法是個死循环,那应该怎么办呢,比如说像下面这样:
public void square(int n){
for(;;){}
}
  如果测试的时候遇到死循环,你的脸上绝对不会露出笑容的。因此,对于那些逻辑很复杂,循环嵌套比较深的、有可能出现死循环的程序,因此壹定要采取壹些预防措施。限时测试是壹個很好的解决方案。我们给这些测试函数设定壹個预期的执行时间,超过了这壹时间,他们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些 Bug 了。要实现这壹功能,只需要给 @Test 标注加壹個参数timeout即可,代码如下:
@Test(timeout=2000L)
public void testSquare() {
calculator.square(3);
assertEquals(9, calculator.getReuslt());
}
  timeout参数表明了你预计该方法运行的时长,单位为毫秒,因此2000就代表2秒。现在我们让这個测试方法运行壹下,看看失败时是什么效果。
  使用@Test 的属性expected来监控测试方法中可能会抛出的某些异常
  JAVA中的异常处理也是壹個重点,因此你经常会编写壹些需要抛出异常的函数。如果你觉得壹個函数应该抛出异常,但是它没抛出,这算不算 Bug 呢?这当然是Bug,JUnit 也考虑到了这壹点,并且可以帮助我们找到这种 Bug。例如,我们写的计算器类有除法功能,如果除数是壹個0,那么必然要抛出“除0异常”。因此,我们很有必要对这些进行测试。代码如下:
@Test(expected=java.lang.ArithmeticException.class)
public void testDivide(){
calculator.divide(0);
}
  如上述代码所示,我们需要使用@Test注解中的expected属性,将我们要检验的异常(这里是 java.lang.ArithmeticException)传递给他,这样 JUnit 框架就能自动帮我们检测是否抛出了我们指定的异常。
  指定 JUnit 运行测试用例时的 Runner
  大家有没有想过这個问题,当你把测试代码提交给JUnit框架后,框架是如何来运行你的代码的呢?答案就是Runner。在JUnit中有很多个Runner,他们负责调用你的测试代码,每壹個Runner都有其各自的特殊功能,你要根据需要选择不同的Runner来运行你的测试代码。可能你会觉得奇怪,前面我们写了那么多测试,并没有明确指定壹個Runner啊?这是因为JUnit中有壹個默认的Runner,如果你没有指定,那么系统会自动使用默认Runner来运行你的代码。换句话说,下面两段代码含义是完全壹样的:
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class CalculatorTest {
...//省略此处代码
}
//用了系统默认的JUnit4.class,运行效果完全壹样
public class CalculatorTest {
...//省略此处代码
}



 从上述例子可以看出:
  1、要想指定壹個 Runner ,需要使用 @RunWith 标注,并且把你所指定的 Runner 类名作为参数传递给它,在JUnit4.8.2的版本中,系统提供了若干可以直接使用的Runner类型,它们的定义都在包org.junit.runners下面。
  2、注解 @RunWith 是用来修饰类的,而不是用来修饰函数的。只要对壹個类指定了 Runner ,那么这个类中的所有函数都被这个 Runner 来调用。
  3、在使用注解@RunWith时,要在头部包含相应的包名,上面的例子对这壹点写的很清楚了。
  接下来,我会向你们展示其他 Runner 的特有功能。
  使用参数化测试完成需要录入大量数据的测试
  你可能遇到过这样的函数,它的参数有许多特殊值,或者说他的参数分为很多个区域。比如,壹個对考试分数进行评价的函数,返回值分别为“优秀,良好,壹般,及格,不及格”,因此你在编写测试的时候,至少要写5個测试,把这五种情况都包含了,这确实是壹件很麻烦的事情。这里我们仍然使用先前的例子,测试壹下square()这个函数,暂且分三类:正数、0、负数。测试代码如下:
package net.oschina.bairrfhoinn.test;
import static org.junit.Assert.*;
import net.oschina.bairrfhoinn.main.Calculator;
import org.junit.Before;
import org.junit.Test;
public class AdvancedTest {
private static Calculator calculator = new Calculator();
@Before
public void setUp() throws Exception {
calculator.clear();
}
@Test
public void testSquare1(){
calculator.square(2);
assertEquals(4, calculator.getReuslt());
}
@Test
public void testSquare2(){
calculator.square(0);
assertEquals(0, calculator.getReuslt());
}
@Test
public void testSquare3(){
calculator.square(-3);
assertEquals(9, calculator.getReuslt());
}
}
  为了简化类似的测试,JUnit4提出了“参数化测试”的概念,只写壹個测试函数,把这若干种情况的输入参数和预期的运行结果放在集合中,然后将这個集合作为参数传递进去,壹次性的完成测试。代码如下:
package net.oschina.bairrfhoinn.test;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import net.oschina.bairrfhoinn.main.Calculator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class SquareTest {
@Parameters
public static Collection prepareData(){
return Arrays.asList(new Object[][]{{2,4},{0, 0},{-3, 9}});
}
public SquareTest(int param, int result){
this.param = param;
this.result = result;
}
@Test
public void square(){
calculator.square(param);
assertEquals(result, calculator.getReuslt());
}
private int param;
private int result;
private static Calculator calculator = new Calculator();
}

posted @ 2013-10-15 11:29 顺其自然EVO 阅读(12130) | 评论 (2)编辑 收藏

cgroup--cgroup 测试

 cgroups全称control groups,在RHEL6的2.6.32内核中已经包括了cgroup的patch。这里强烈建议安装RHEL6(CentOS6)来使用cgroups,如果没有的话,
  只能升级内核了 ( > 2.6.26版本)
  安装cgroups
  apt-get install cgroup-bin
  改变配置:vi /etc/cgconfig.conf
  将最后的mount 改为如下形式:
mount {
cpuset = /sys/fs/cgroup/cpuset;
net_cls = /sys/fs/cgroup/net_cls;
blkio = /sys/fs/cgroup/blkio;
perf_event = /sys/fs/cgroup/perf_event;
cpu = /sys/fs//cgroup/cpu;
cpuacct = /sys/fs/cgroup/cpuacct;
devices = /sys/fs/cgroup/devices;
memory = /sys/fs/cgroup/memory;
freezer = /sys/fs/cgroup/freezer;
}
  测试 cpu 子系统
  cpu.shares:假设cgroup A的 tasks 的 cpu.shares 值为1,cgroup B的tasks的cpu.shares值为2,则cgroup B的进程占用的cpu时间是cgroup A上进程的2倍。
  cpu.rt_runtime_us
  cpu.rt_period_us:  这两个值建议不要设,让OS去调度占用的CPU时间的绝对值。
  进入 cpu 目录:
  sina@ubuntu:~$ cd /sys/fs/cgroup/cpu
  创建目录:
  # mkdir   tinker
  # mkdir   tailor
  下面通过taskset -c 3 ,启动两个虚拟机  并指定其 cpu affinity为cpu 3,启动2个虚拟机:
  # taskset -c 3 ./for-test.sh
  并在每个虚拟机中 满负荷运行 计算密集型程序。
  观察两台虚拟机的PID,及cpu使用率:
root@ubuntu:~# ps -C qemu-system-i386 -opid,%cpu,psr,args
PID %CPU PSR COMMAND
3237 50.1   3 /home/sina/Downloads/qemu-kvm-1.1.0/i386-softmmu/qemu-system-i386
3306 49.8   3 /home/sina/Downloads/qemu-kvm-1.1.0/i386-softmmu/qemu-system-i386
  此时把两个qemu 任务的 pid分别 echo 进 tasks 文件中。并且修改  cpu/tinker  的 cpu.shares 为2048, cpu/tailor  的 cpu.shares 为512:
root@ubuntu:~# echo 3237 > /sys/fs/cgroup/cpu/tinker/tasks
root@ubuntu:~# echo 3306 > /sys/fs/cgroup/cpu/tailor/tasks
root@ubuntu:~# echo 2048 > /sys/fs/cgroup/cpu/tinker/cpu.shares
root@ubuntu:~# echo 512 > /sys/fs/cgroup/cpu/tailor/cpu.shares
  此时观察两个任务的 cpu 使用率:
root@ubuntu:~# ps -C qemu-system-i386 -opid,%cpu,psr,args
PID %CPU PSR COMMAND
3237 80   3 /home/sina/Downloads/qemu-kvm-1.1.0/i386-softmmu/qemu-system-i386
3306 20   3 /home/sina/Downloads/qemu-kvm-1.1.0/i386-softmmu/qemu-system-i386
  设置了cpu.shares之后CPU利用率不会立刻就变为shares指定的那样,需要等待一段时间,基本上是个曲线的变化过程,之后就按照设置的数值来分配cpu使用率。
  (须待以后在测试!!)

posted @ 2013-10-15 11:25 顺其自然EVO 阅读(454) | 评论 (0)编辑 收藏

压力测试和评测工具 Siege

 Siege是一个压力测试评测工具,设计用于WEB开发这评估应用在压力下的承受能力:可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行。
  测试实例:
Ben: $ siege -u shemp.whoohoo.com/Admin.jsp -d1 -r10 -c25
..Siege 2.65 2006/05/11 23:42:16
..Preparing 25 concurrent users for battle.
The server is now under siege...done
Transactions: 250 hits
Elapsed time: 14.67 secs
Data transferred: 448000 bytes
Response time: 0.43 secs
Transaction rate: 17.04 trans/sec
Throughput: 30538.51 bytes/sec
Concurrency: 7.38
Status code 200: 250
Successful transactions: 250
Failed transactions: 0

posted @ 2013-10-15 11:24 顺其自然EVO 阅读(238) | 评论 (0)编辑 收藏

安装TOMCAT+JAVA

 1:安装java
if [ -d /opt/soft/java ];then
mv /opt/soft/java /opt/soft/java_$(date +%Y%m%d-%H-%M-%S)
fi
cd /opt/soft/
wget http://10.4.16.2/pub/tomcat_java/jdk-6u38-x64.tar.gz
tar zxvf jdk-6u38-x64.tar.gz
rm -rf jdk-6u38-x64.tar.gz
  2:安装tomcat
if [ -d /opt/soft/tomcat ];then
mv /opt/soft/tomcat /opt/soft/tomcat_$(date +%Y%m%d-%H-%M-%S)
fi
cd /opt/soft/
wget http://10.4.16.2/pub/tomcat_java/tomcat-7.0.34.tar.gz
tar zxvf tomcat-7.0.34.tar.gz
yum -y install tomcat-native apr apr-devel
rm -f tomcat-7.0.34.tar.gz
rm -f /etc/rc3.d/*tomcatd
wget -O /etc/rc.d/init.d/tomcat http://10.4.16.2/pub/tomcat_java/tomcat.init
chown root:root /etc/rc.d/init.d/tomcat
chmod 755 /etc/rc.d/init.d/tomcat
chkconfig --add tomcat
chkconfig --level 345 tomcat on
  3:安装第二个tomcat
cd /opt/soft
cp -rf tomcat tomcat1
wget -O /etc/rc.d/init.d/tomcat1 http://10.4.16.2/pub/tomcat_java/tomcat1.init
chown root:root /etc/rc.d/init.d/tomcat1
chmod 755 /etc/rc.d/init.d/tomcat1
chkconfig --add tomcat1
chkconfig --level 345 tomcat1 on
sed -i '/^CATALINA_PID=$TOMCAT_HOME\/logs\/tomcat.pid/i\export TOMCAT_HOME=/opt/soft/tomcat1' /opt/soft/tomcat1/bin/catalina.sh
  修改tomcat服务端口和shutdown端口
  端口规范
 实例1服务端口shutdown端口实例2服务端口shutdown端口实例3服务端口shutdown端口
情况1tomcat808005tomcat1818006tomcat2828007
情况2tomcat80808005tomcat180818006tomcat280828007

  4:安装第三个tomcat
  同二,需要略加修改

posted @ 2013-10-15 11:22 顺其自然EVO 阅读(242) | 评论 (0)编辑 收藏

闪回数据库(Flashback Database)

  Flashback Database闪回数据库
  使用闪回数据库可以将数据库快速的闪回到过去某个时间点。在启用闪回数据时,会将修改过的块的前映像作为闪回数据库日志保存在闪回恢复区中,如出现逻辑坏块或用户错误操作需要恢复到过去的时间点,闪回数据库将还原数据库的前映像,然后使用归档日志和redo前滚到期望恢复的时间点,因为无需还原数据库的数据文件,所有此过程速度比较传统的还原恢复通常快很多。
  启动闪回数据库时,会将前映像数据保存在“闪回缓冲区”中,然后由恢复写入器(Recovery Writer,RVWR)后台进程,将闪回缓冲区的前映像数据保存在闪回恢复区的闪回数据库日志中。
  配置闪回数据库相关参数:
  db_recovery_file_dest  决定闪回恢复区路径
  db_recovery_file_dest_size  决定闪回恢复区大小
  db_flashback_retention_target  保留恢复最近多长时间的数据,单位为分钟。
  闪回数据库必须在归档模式下
  开启归档
  1、SQL> alter system set  log_archive_dest_1='location=+oradg/b1/recovery/' scope=both;
  2、SQL> shutdown immediate
  3、SQL>  startup mount
  4、SQL> alter database archivelog;
  5、SQL> alter database open;
  6、SQL> archive log list
  设置闪回区大小,路径,闪回保留时间
SQL> alter system set db_recovery_file_dest_size=5G;
System altered.
SQL> alter system set db_recovery_file_dest='+ORADG';
System altered.
SQL> alter system set db_flashback_retention_target=2880;
System altered.
开启闪回功能
SQL> startup mount exclusive
SQL> alter database flashback on;
Database altered.
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
  关闭闪回功能
SQL> startup mount exclusive
ORACLE instance started.
Total System Global Area  839282688 bytes
Fixed Size                  2217992 bytes
Variable Size             557844472 bytes
Database Buffers          276824064 bytes
Redo Buffers                2396160 bytes
Database mounted.
SQL> ?alter database flashback off;
Database altered.
SQL> alter database open ;
Database altered.
SQL> alter system set db_recovery_file_dest='';
System altered.

闪回数据库的步骤
  1、关闭数据库
  2、启动数据库到mount状态[exclusive模式]
  3、闪回至某个时间点,SCN或还原点
  4、使用resetlogs打开数据库
  闪回数据库的方法
  1、sqlplus下基于SCN闪回
  FLASHBACK  DATABASE [<database_name>]  TO  SCN <system_change_number>
  2、sqlplus下基于时间戳闪回
  FLASHBACK  DATABASE [<database_name>]  TO  TIMESTMP <system_timestamp_value>
  3、sqlplus下基于还原点闪回
  FLASHBACK  DATABASE [<database_name>]  TO  RESTORE POINT <restore_point_name>
  4、RMAN下基于时间戳闪回
  RMAN> FLASHBACK DATABASE TO TIME = "TO_DATE('2013-10-10 19:25:21','YYYY-MM-DD HH24:MI:SS')";
  5、RMAN下基于SCN闪回
  RMAN> FLASHBACK DATABASE TO SCN=1121679;
  6、RMAN下基于:归档序号
  RMAN> FLASHBACK DATABASE TO SEQUENCE=56 THREAD=1;
  运用闪回功能示例:
  示例1:删除表的部分数据后,使用闪回数据库的方法恢复
SQL> create table test_flashback as select * from emp;  --创建表
Table created.
SQL> select dbms_flashback.get_system_change_number from dual; --记录删除数据前scn
GET_SYSTEM_CHANGE_NUMBER
------------------------
1069396
SQL> delete from test_flashback where deptno=20;      --删除数据
5 rows deleted.
SQL> commit;
Commit complete.
SQL> startup mount exclusive              --启动到mount exclusive状态
ORACLE instance started.
Total System Global Area  839282688 bytes
Fixed Size                  2217992 bytes
Variable Size             557844472 bytes
Database Buffers          276824064 bytes
Redo Buffers                2396160 bytes
Database mounted.
SQL> flashback database to scn 1069396;  --闪回到删除数据之前,还可以用时间戳闪回如:
Flashback complete.                                    --flashback database to to_timestamp('2013-10-8 18:02:34','YYYY-MM-DD HH24:MI:SS')
SQL> alter database open read only;    ?--以read only 方式打开检查数据库是否闪回成功,如不成功考虑其他形式的闪回
Database altered.
SQL> select * from scott.test_flashback where deptno=20;
EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH      CLERK           7902 17-DEC-80        800                    20
7566 JONES      MANAGER         7839 02-APR-81       2975                    20
7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
SQL> startup
ORACLE instance started.
Total System Global Area  839282688 bytes
Fixed Size                  2217992 bytes
Variable Size             557844472 bytes
Database Buffers          276824064 bytes
Redo Buffers                2396160 bytes
Database mounted.
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
SQL> alter database open resetlogs;
Database altered.
  --闪回数据库之后,最后做一次全备

posted @ 2013-10-15 11:21 顺其自然EVO 阅读(231) | 评论 (0)编辑 收藏

如何在网页读取用户IP,操作系统版本等数据demo

  我们浏览网页的时候,会不经意间看到,有些地方(如个人的签名档)显示出了个人的IP,操作系统等数据.借助第三方API和请求报头useragent是很容易实现的.
<html>
<head>
<title>Sherry</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://counter.sina.com.cn/ip/" charset="gb2312"></script>
<script>
document.writeln("IP地址:"+ILData[0]+"<br />");           //输出接口数据中的IP地址
document.writeln("地址类型:"+ILData[1]+"<br />");         //输出接口数据中的IP地址的类型
document.writeln("地址类型:"+ILData[2]+"<br />");         //输出接口数据中的IP地址的省市
document.writeln("地址类型:"+ILData[3]+"<br />");         //输出接口数据中的IP地址的
document.writeln("地址类型:"+ILData[4]+"<br />");         //输出接口数据中的IP地址的运营商
//document.write(navigator.userAgent + "<br>");
document.write("您的操作系统版本为:");
if(navigator.userAgent.indexOf("Windows NT 6.2") > 0){
document.write("Windows 8");
}
else if(navigator.userAgent.indexOf("Windows NT 6.1") > 0){
document.write("Windows 7");
}
else if(navigator.userAgent.indexOf("Windows NT 6.0") > 0){
document.write("Windows Vista");
}
else if(navigator.userAgent.indexOf("Windows NT 5.2") > 0){
document.write("Windows 2003");
}
else if(navigator.userAgent.indexOf("Windows NT 5.1") > 0){
document.write("Windows xp");
}
else if(navigator.userAgent.indexOf("Windows NT 5.0") > 0){
document.write("Windows 2000");
}
</script>
</head>
<body>
</body>
</html>
  显示:

posted @ 2013-10-15 11:20 顺其自然EVO 阅读(468) | 评论 (0)编辑 收藏

Selenium2.0功能测试之访问站点及获取页面信息

 Selenium为访问站点提供了两种方式:
  driver.get("URL");   #个人推荐这种方式,因为能少写一个字符是一个字符啊。
  driver.navigate().to("URL");
  页面的Title主要用于case的验证,当然了也有一位大神教育我说case不够title来凑,这个作用显著啊!
  页面的URL也主要是用于case的验证,URL的一个重要的测试领域就是对于重定向的测试(很多地址当你访问后会自动的跳转到其他的地址,这时URL 验证的机会就来了,当然了还是有很多其他的地方能用到一时想不出来了就这些吧!)
package org.coderinfo.demo;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class GetWebSiteAndPrintWebInfo {
private static final String URL = "http://www.google.com.hk";
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize(); //最大化浏览器界面
driver.get(URL); // 等同于 driver.navigate().to(URL); 访问谷哥的首页 ,此处放弃度娘。
String title = driver.getTitle(); //获取当前页面的title
String currentUrl = driver.getCurrentUrl(); // 获取当前页面的URL
System.out.printf("Current page's title is: %s , Current URL is: %s \n",title,currentUrl);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.quit();  //彻底退出WebDriver
}
}
相关文章
Selenium2.0功能测试之forward与back
Selenium2.0功能测试之设置浏览器大小

posted @ 2013-10-14 10:19 顺其自然EVO 阅读(671) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 195 196 197 198 199 200 201 202 203 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜