• $ cat nginx.log |awk '{print $9}'|grep '400\|500'|head -3
    500
    400
    500


  • 作业

    Shopping.buys方法的单元测试;

    要求:测试覆盖所有不同逻辑分支,并保证每次运行测试都可以正常执行;
    使用数据驱动、注解(Before、After)、配置(testng.xml)等。

    测试数据准备(用EXCEL存数据)

    BeforeClass

    BeforeMethod(setUp)

    Test(用数据驱动测试)

    pom.xml 配置

    <configuration>
    <forkMode>once</forkMode>
    <argLine>-Dfile.encoding=UTF-8</argLine>
    <argLine>
    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
    </argLine>
    <!-- 忽略测试fail,继续编译 -->
    <testFailureIgnore>true</testFailureIgnore>
    <suiteXmlFiles>
    <suiteXmlFile>exceltestng.xml</suiteXmlFile>
    </suiteXmlFiles>
    </configuration>

    exceltestng.xml 配置

     <classes>
    <class name="testXunit.BuysTest">
    <methods>
    <include name="testBuys"></include>
    </methods>
    </class>
    </classes>

    测试代码

    package testXunit;

    import DemoXunit.BuysState;
    import DemoXunit.Login;
    import DemoXunit.Products;
    import DemoXunit.Shopping;
    import MyData.ExcelData;
    import io.qameta.allure.Description;
    import org.testng.Assert;
    import org.testng.annotations.AfterClass;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.BeforeMethod;
    import org.testng.annotations.Test;

    import java.io.FileNotFoundException;
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;

    public class BuysTest {

    Shopping shopping = new Shopping();
    HashMap<Integer, Integer> pscount = new HashMap<Integer, Integer>();
    HashMap<Integer, Integer> prePIdCount = new HashMap<Integer, Integer>();

    @BeforeClass(description = "测试套数据初始化")
    public void beforeClass() throws NoSuchMethodException, FileNotFoundException {
    //数据备份,只备份使用的数据
    Method beforeClass = this.getClass().getMethod("beforeClass");
    Iterator<Object[]> it = new ExcelData().dataForTestMethod(beforeClass, Integer.class);
    while (it.hasNext()) {
    Object[] o = it.next();
    int proId = (Integer) o[0];
    pscount.put(proId, shopping.getPro(proId).getCount());
    }
    System.out.println(it);
    //数据预置,用于setUp
    setPIdCount();

    }

    @BeforeMethod(description = "测试用例数据初始化")
    public void setUp() {
    //隔离每次执行的数据
    Iterator<Map.Entry<Integer, Integer>> it = prePIdCount.entrySet().iterator();
    while (it.hasNext()) {
    Map.Entry<Integer, Integer> next = it.next();
    int proId = next.getKey();
    int count = next.getValue();
    shopping.getPro(proId).setCount(count);
    }
    }

    private void setPIdCount() throws NoSuchMethodException, FileNotFoundException {
    Method setUp = this.getClass().getMethod("setUp");
    Iterator<Object[]> it = new ExcelData().dataForTestMethod(setUp, Integer.class, Integer.class);
    System.out.println("it=" + it);
    while (it.hasNext()) {
    Object[] o = it.next();
    int proId = (Integer) o[0];
    int count = (Integer) o[1];
    prePIdCount.put(proId, count);
    }
    }


    @Description("Buys方法描述")
    @Test(dataProvider = "ExcelData", dataProviderClass = MyData.ExcelData.class,description = "Buys方法测试")
    public void testBuys(String caseId, boolean isLogin, int proId, int count, int expected, String caseTitle) {
    System.out.println(caseId + ",登录状态:" + isLogin + ",产品id:" + proId + ",购买数量:" + count + ",期望值:" + expected + ",用例标题:" + caseTitle);

    Login.isLogin = isLogin;
    Products products = shopping.getPro(proId);//获取商品信息
    int beforeProCount = products.getCount();//获取购买前数量
    int afterProCount = beforeProCount;//获取购买后数量
    int buysState = shopping.buys(proId, count);//购买商品
    if (expected == 1) {//购买成功数量减
    afterProCount = beforeProCount - count;
    }
    int proCount = products.getCount();//购买后实际数量
    返回值校验
    Assert.assertEquals(buysState, expected);//返回值校验
    商品数量变更校验
    Assert.assertEquals(afterProCount, proCount);//商品数量变更校验
            String sysoutString = "是否登录:" + isLogin + ",购买商品id:" + proId + ",商品名称:" + products.getProName()
    + ",商品库存:" + beforeProCount + ",购买数量:" + count + ",剩余数量:" + proCount + ",期望购买状态:"
    + expected + "[" + BuysState.getDescriptionById(expected) + "],casetitle:" + caseTitle;
    System.out.println(sysoutString);
    }


    @AfterClass
    public void afterClass() {
    //数据还原,从pscount里面还原
    Iterator<Map.Entry<Integer, Integer>> it = pscount.entrySet().iterator();
    while (it.hasNext()) {
    Map.Entry<Integer, Integer> pidcount = it.next();
    shopping.getPro(pidcount.getKey()).setCount(pidcount.getValue());
    }
    }

    }

    执行结果

    1输入条件proId没有判断,产生NEP

    2红框代码无法覆盖,没有多线程,没有static

  • 1、提取系统state连接种类

    Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name

    netstat.sh

    #! /bin/bash
    # 输出netstat 的stat字段
    netstat=($(netstat -antu|sed '1,2d'|awk '{print $6}'|sort -u));
    count=${#netstat[@]};
    echo tcp/udp连接的state共有${count};
    for((i=0;i<${count};i++));
    do
    echo 第$((i+1)):${netstat[$i]};
    done

    输出结果

    $ bash netstat.sh 
    tcp/udp连接的state共有2
    1:ESTABLISHED
    2:LISTEN

    2、teserhome 某一精华帖任意一回复贴的数量

    任意一个精华帖会有多个回复、找出任意一个回复贴的点赞数

    zan.sh

    #! /bin/bash
    # 获取任意一个精华帖回复赞数,统计删除回复楼层,未删除回复楼层,不统计非回复贴,如其他贴提及此贴,将此贴设置为精华等楼层
    # 需要登录的帖子未做过滤,直接当做0回复
    url=https://testerhome.com;
    #获取总页数
    pages=$(curl -s ${url}/topics/excellent|grep -o 'href="/topics/excellent?page=[0-9]*"'|awk -F "\"|=" '{print $4}'|sort -un|sed -n '$p');
    echo -e "精华帖总页数:\033[31m$pages\033[0m";
    #获取随机页数
    pge=$((RANDOM%pages+1));
    echo -e "随机精华帖页数:\033[31m$pge\033[0m";
    #获取pge页的帖子uri
    pgeuri=($(curl -s ${url}/topics/excellent?page=$i|grep -o 'href="/topics/[0-9]*"'|awk -F '"' '{print $2}'));
    #随机选取pgeuri
    index=$((RANDOM%${#pgeuri[*]}));
    uri=${pgeuri[index]};
    echo -e "随机选取的精华帖:\033[31m${uri}\033[0m";
    #访问指定帖子uri
    curl -s ${url}${uri}>lines;

    getfz(){
    while read line;
    do
    if [ -n "$(echo $line|grep -o 'data-floor="[0-9]*')" ] ;
    then dfl=$(echo "
    $line"|awk -F '"' '{print $4}');
    elif [ -n "$(echo $line|grep -o 'class="deleted text-center"')" ];
    then fz[$dfl]=第${dfl}楼赞数:楼层已删,赞数未知;flag=1;
    elif [ -n "$(echo $line|grep -o 'class="author-only-no-content"')" ];
    then fz[$dfl]=第${dfl}楼赞数:仅楼主可见,赞数未知;flag=1;
    elif [ -n "$(echo $line|grep -o '.*.data-type="Reply"')" ];
    then fz[${dfl}]=第${dfl}楼赞数:$(echo $line|awk -F '"' '{print $4}');
    flag=1;
    else
    #非回复贴不统计
    flag=0;
    fi;
    done < lines;
    }
    echo -e "\033[31m正在收集回复信息... \033[0m";
    getfz;
    #获取回复总楼层
    replys=${#fz[*]};
    echo 回复总楼层数:$replys;
    getAllfz(){
    #获取随机楼层数+1没有0
    randfl=$((RANDOM%${replys}+1));
    #获取指定楼层赞数
    echo 随机楼层赞数:${fz[$randfl]};
    echo -e "\033[31m开始遍历楼层赞数,非回复贴不统计...\033[0m";
    for z in ${fz[*]};
    do
    isnum=$(echo "$z"|awk -F ':' '{print $NF}'|grep -o '[0-9]*');
    if [[ -n "$isnum" && "$isnum" -gt 0 ]];
    then echo -e "\033[32m${z} \033[0m";
    elif [[ "$z" == *赞数未知* ]];
    then echo -e "\033[31m${z} \033[0m";
    else
    echo $z;
    fi
    done
    }

    echofz(){
    if [ 0 -eq $replys ];
    then echo "帖子0回复"
    elif [ 1 -eq $replys ];
    then echo "帖子只有1个回复:${z[*]}";#只有1个元素直接输出所有
    else
    getAllfz;
    fi;
    }
    echofz;

    输出结果

    $ bash zan.sh 
    精华帖总页数:43
    随机精华帖页数:13
    随机选取的精华帖:/topics/17117
    正在收集回复信息...
    回复总楼层数:14
    随机楼层赞数:第4楼赞数:0
    开始遍历楼层赞数,非回复贴不统计...
    1楼赞数:2
    2楼赞数:1
    3楼赞数:0
    4楼赞数:0
    5楼赞数:0
    6楼赞数:0
    7楼赞数:0
    9楼赞数:0
    10楼赞数:0
    11楼赞数:0
    12楼赞数:0
    13楼赞数:0
    18楼赞数:楼层已删,赞数未知
    19楼赞数:0

  • cat 1206_2.log | sed -n '/07:48:00/,/07:52:00/p'
    这个里面的/07:48:00/,/07:52:00/这个用法不怎么明白,就比如说下面的第2sed -n '/00:00:01/,/00:00:02/p为什么不是0102的也打印了?
    $ cat -n 1206_2.log|head -n 20|awk -F "GET" '{print $1}'|sed -n '/00:00:02/,/00:00:01/p'
    2 123.125.71.60 - - [05/Dec/2018:00:00:02 +0000] "
    3 141.8.142.131 - - [05/Dec/2018:00:00:02 +0000] "

    4 139.180.131.123 - - [05/Dec/2018:00:00:01 +0000] "
    $ cat -n 1206_2.log|head -n 20|awk -F "
    GET" '{print $1}'|sed -n '/00:00:01/,/00:00:02/p'
    1 223.104.7.59 - - [05/Dec/2018:00:00:01 +0000] "

    2 123.125.71.60 - - [05/Dec/2018:00:00:02 +0000] "
    4 139.180.131.123 - - [05/Dec/2018:00:00:01 +0000] "

    5 40.77.167.60 - - [05/Dec/2018:00:00:03 +0000] "
    6 204.141.42.226 - - [05/Dec/2018:00:00:04 +0000] "

    7 40.77.167.60 - - [05/Dec/2018:00:00:04 +0000] "
    8 127.0.0.1 - - [05/Dec/2018:00:00:04 +0000] "

    9 139.180.131.123 - - [05/Dec/2018:00:00:01 +0000] "
    10 117.136.39.87 - - [05/Dec/2018:00:00:01 +0000] "

    11 121.15.166.147 - - [05/Dec/2018:00:00:07 +0000] "
    12 219.142.131.122 - - [05/Dec/2018:00:00:07 +0000] "

    13 61.132.54.2 - - [05/Dec/2018:00:00:07 +0000] "
    14 103.75.152.102 - - [05/Dec/2018:00:00:07 +0000] "

    15 222.66.96.129 - - [05/Dec/2018:00:00:07 +0000] "
    16 180.168.166.28 - - [05/Dec/2018:00:00:07 +0000] "

    17 114.94.126.62 - - [05/Dec/2018:00:00:07 +0000] "
    18 61.135.169.90 - - [05/Dec/2018:00:00:07 +0000] "

    19 120.36.255.107 - - [05/Dec/2018:00:00:07 +0000] "
    20 14.21.33.152 - - [05/Dec/2018:00:00:07 +0000] "

  • curl https://testerhome.com 2>/dev/null|grep "fa fa-diamond"  

    里面的grep匹配的行怎么界定行首和行尾?

  • []、[[]]、()、(())这几个括号很容易混淆,怎么区分?

  • 在web端测试的时候,shell基本就那么几个命令,不知道测开的要求是要掌握哪些和掌握什么程度?

  • @zyanycall 可以share一下你的ideal吗

  • @information 可以贴一下 获取测试数据对应行 的代码吗?O(∩_∩)O谢谢

  • @terrychow 可以贴一下 获取测试数据对应行 的代码吗?O(∩_∩)O谢谢