前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【原创】爆肝23页教程,自研关键字驱动框架

【原创】爆肝23页教程,自研关键字驱动框架

作者头像
dongfanger
发布于 2023-11-11 01:24:56
发布于 2023-11-11 01:24:56
48500
代码可运行
举报
文章被收录于专栏:dongfangerdongfanger
运行总次数:0
代码可运行

tep关键字驱动框架教程

tep简介

tepTry Easy Pytest的首字母缩写,关键字驱动框架,专注于接口自动化测试,单个文件即可完成用例编写。

设计理念

✔️稳定:基于成熟框架pytest,天生强大

✔️规范:RobotFramework风格,井井有条

✔️统一:关键字命名与JMeter组件一致,一知万用

✔️原生:关键字用法保留Python原生定义,轻车熟路

✔️兼容:分层机制保证迭代升级不影响老项目,向下兼容

❌拒绝低代码平台,开发成本太高。

❌拒绝EXCEL/YAML,调试太麻烦。

❌拒绝深度编程,绕来绕去太复杂。

✌️只需要一点点Python基础,就能轻松搞定接口自动化。

快速入门

安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install tep

验证安装成功:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tep -v
Current Version: V2.0.0

 ____o__ __o____   o__ __o__/_   o__ __o
  /   \   /   \   <|    v       <|     v\
       \o/        < >           / \     <\
        |          |            \o/     o/
       < >         o__/_         |__  _<|/
        |          |             |
        o         <o>           <o>
       <|          |             |
       / \        / \  _\o__/_  / \

新建项目

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tep -s demo
Created folder: demo
Created folder: demo/case
Created folder: demo/data
Created folder: demo/report
Created file:   demo/run.py
Created file:   demo/conftest.py
Created file:   demo/pytest.ini
Created file:   demo/.gitignore.py
Created file:   demo/case/__init__.py
Created file:   demo/case/test_demo.py
Created file:   demo/data/UserDefinedVariables.yaml

编写用例

case/test_demo.py编写用例,脚手架已自动生成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def test(HTTPRequestKeyword):
    ro = HTTPRequestKeyword("get", url="http://httpbin.org/status/200")
    assert ro.response.status_code == 200

执行run.py后出现以下日志:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
URL: http://httpbin.org/status/200
Method: GET
Headers: {"User-Agent": "python-requests/2.31.0", "Accept-Encoding": "gzip, deflate", "Accept": "*/*", "Connection": "keep-alive"}
Request Body: None
Status Code: 200
Response Body: 
Elapsed: 0.61046s

恭喜您,上手成功!

基础语法

tep框架是编写Python代码的,需要具备一些Python基础。不过无需担心,只要简单入门即可。

Python文件

Python文件是以.py结尾的。可以使用python filename.py命令执行,也可以在PyCharm中右键点击Run按钮执行。

Python语句

一条语句完成一件事,比如打印日志、发送HTTP请求。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
print("Hello, Python!")

Python变量

简单理解,= 符号左边的就是变量,变量用来存储数据。

Python数据类型

Number(数字)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
x = 123

String(字符串)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
s = "cekaigang"

List(列表)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
skills = ["测试", "开发"]
# 索引取值
skills[0]

Tuple(元组)

也就是不可变列表。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tup3 = (1, 2, 3)
# 索引取值
tup3[0]

Set(集合)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 用于求交集、并集等
sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}

Dictionary(字典)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
c = {"x": 1, "y": 2}
# 中括号key取值
c["x"]

Python缩进

Python语言特点就是使用4个空格来控制代码块。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def hello() :
    print("Hello World!")

Python函数

函数定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 函数名(参数列表):
    函数体

tep用例就是写在一个test()函数里面的。

函数调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 使用小括号来调用
UserDefinedVariablesKeyword()
# 将函数返回值存入变量
ro = UserDefinedVariablesKeyword()
# 给函数传参,参数可以只传值,也可以传键值对key=value
ro = HTTPRequestKeyword("get", url="http://httpbin.org/status/200")

Python对象

对象包含字段和方法,使用.符合来访问。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 字段
response.status_code
# 方法
response.json()

Python导入

从其他文件导入代码到当前文件使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from tep.utils.Parewise import pairwise

没错,就是这么简单,掌握这些基础语法就能开始使用tep框架了。

框架语法

tep命令

tep -v,等同于tep --version,查看版本

tep -s,等同于tep --startproject,新建项目

关键字语法

关键字不需要import就能使用,将关键字传入test()函数即可。

关键字以Keyword单词结尾,在输入K时能获得语法提示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def test(Keyword):
    # 返回结果 = 关键字(参数)
    ro = Keyword(param)

关键字跟Python函数用法一样,接受传入参数,执行某个动作,返回操作结果。

关键字概览

框架内置关键字

  • HTTPRequestKeyword 发送HTTP请求
  • BodyKeyword 对接口参数进行参数化
  • UserDefinedVariablesKeyword 用户自定义变量
  • DataKeyword 读取data目录下文件
  • DbcKeyword 数据库连接

用户自定义关键字

  • login 登录
  • mysql_execute 执行sql

更多关键字内容请阅读“高级用法>关键字详解”章节内容。

代码规范

  1. 一条语句写在一行,不换行,超长时建议通过变量拆成多条语句
  2. 关键字返回Result对象,可命名为ro,通过ro.取值
  3. 遵守PEP8,祝您写出漂亮代码

目录结构

  • case 存放用例文件
  • data 存放数据文件
  • report 存放报告文件
  • run.py 执行用例入口

用例管理

  1. 用例全部写在一个文件里面,从上往下分成多个段落,每个段落视为一个测试步骤。用例由多个测试步骤组成。
  2. 测试步骤分为①前置数据准备②接口请求③后置数据提取三大部分。步骤由关键字驱动。
  3. 多条用例按不同模块放在不同目录下,由于用例文件完全独立,可以将稳定用例全部放到某个目录下,命名为“基础用例集”,进行持续维护和定时巡检,执行时指定目录即可。

以上是作者建议,用例管理是很灵活的,框架没有做任何限制,可以自由选择。

用例执行有3种主要方式:

  1. run.py执行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from tep.libraries.Run import Run

if __name__ == '__main__':
    settings = {
        "path": ["test_demo.py"],  # Path to run, relative path to case
        "report": False,  # Output test report or not
        "report_type": "pytest-html"  # "pytest-html" "allure"
    }
    Run(settings)
  1. PyCharm执行
  2. pytest命令执行

测试报告

支持2种测试报告,pytst-html和allure。在run.py文件中设置。

默认为pytest-html,无需单独安装,开启后会生成HTML报告到report目录下。

allure需要安装Java环境,然后下载文件,解压后将bin目录添加到系统环境变量Path。

https://github.com/allure-framework/allure2/releases

开启allure报告前请确保已完成安装,否则可能报错找不到allure命令。

断言方法

直接使用Python原生断言,assert语句:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def test_assert_equal():
    assert 1 == 1


def test_assert_not_equal():
    assert 1 != 2


def test_assert_greater_than():
    assert 2 > 1


def test_assert_less_than():
    assert 1 < 2


def test_assert_less_or_equals():
    assert 2 >= 1
    assert 2 >= 2


def test_assert_greater_or_equals():
    assert 1 <= 2
    assert 1 <= 1


def test_assert_length_equal():
    assert len("abc") == len("123")


def test_assert_length_greater_than():
    assert len("hello") > len("123")


def test_assert_length_less_than():
    assert len("hi") < len("123")


def test_assert_length_greater_or_equals():
    assert len("hello") >= len("123")
    assert len("123") >= len("123")


def test_assert_length_less_or_equals():
    assert len("123") <= len("hello")
    assert len("123") <= len("123")


def test_assert_string_equals():
    assert "dongfanger" == "dongfanger"


def test_assert_startswith():
    assert "dongfanger".startswith("don")


def test_assert_regex_match():
    import re
    assert re.findall(r"don.*er", "dongfanger")


def test_assert_contains():
    assert "fang" in "dongfanger"
    assert 2 in [2, 3]
    assert "x" in {"x": "y"}.keys()


def test_assert_type_match():
    assert isinstance(1, int)
    assert isinstance(0.2, float)
    assert isinstance(True, bool)
    assert isinstance(3e+26j, complex)
    assert isinstance("hi", str)
    assert isinstance([1, 2], list)
    assert isinstance((1, 2), tuple)
    assert isinstance({"a", "b", "c"}, set)
    assert isinstance({"x": 1}, dict)

变量管理

全局变量data/UserDefinedVariables.yaml中填写,通过UserDefinedVariablesKeyword()关键字直接读取。

局部变量在用例文件中test()函数内直接定义。

其他变量可以在data目录下新建不同的YAML/JSON文件,通过DataKeyword读取。

接口关联

接口关联是指从上个接口响应取值,将值传入下个接口入参,即参数化。

取值

TepResponse内置了.jsonpath()方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sku_id = response.jsonpath("$.skuId")

默认取匹配到的第一个,更复杂取值使用JSONPath原生方法。

传值

使用BodyKeyword关键字:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
body = r"""{"id":1,"param":"[{\"page\": 1, \"pinList\":[\"cekaigang\"]}]","ext1":{"a":1,"b":1},"ext2":[1,1,1],"ext3":{"name":"pytest"}}"""
ro = BodyKeyword(body, {"$.id": 9, "$.param[0].page": 9, "$.param[0].pinList[0]": "dongfanger", "$.ext1.a": 9, "$.ext2[0]": 9, "$.ext2[2]": 9, "$.ext3.name": "tep"})

第一个参数为JSON字符串,注意使用多行字符串且加上前缀r

第二个参数为表达式,key为JSONPath表达式,value为替换值,支持批量替换。

接口复用

接口复用,或者叫做“用例复用”,通过自定义关键字来实现。可以将多个接口,或者公共用例,自定义为关键字,使用关键字在不同用例之间复用。

高级用法

关键字详解

关键字是tep框架核心,语法统一:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ro = Keyword(param)

任何关键字都遵循这种用法。

tep关键字分为内置和自定义两大类。

内置

内置关键字命名为单词首字母大写且以Keyword结尾。

HTTPRequestKeyword

学习requests.request即可,HTTPRequestKeyword使用方法完全一样。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ro = HTTPRequestKeyword("get", url="http://httpbin.org/status/200")

HTTPRequestKeyword关键字返回Result对象,通过ro.response获取requests.Reponse对象。

BodyKeyword

第一个参数为JSON字符串,注意使用多行字符串且加上前缀r

第二个参数为表达式,key为JSONPath表达式,value为替换值,支持批量替换。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ro = BodyKeyword(body, {"$.id": 9, "$.param[0].page": 9, "$.param[0].pinList[0]": "dongfanger", "$.ext1.a": 9, "$.ext2[0]": 9, "$.ext2[2]": 9, "$.ext3.name": "tep"})

BodyKeyword关键字返回Result对象,通过ro.data获取替换后JSON。

UserDefinedVariablesKeyword

不需要传参,直接使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ro = UserDefinedVariablesKeyword()

UserDefinedVariablesKeyword关键字返回Result对象,通过ro.data获取解析后字典。

DataKeyword

入参为文件路径,data目录相对路径。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ro = DataKeyword("data.json")

DataKeyword关键字返回Result对象,通过ro.data获取解析后字典。

自定义

自定义关键字命名为小写加下划线。需要用户输入数据的关键字为自定义关键字,比如登录信息、数据库连接信息。

自定义关键字需要新建fixture文件夹,文件名以fixture_开头才能识别:

login

使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def test(login):
    ro = login()
    print(ro.data)

定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import pytest

from tep.libraries.Result import Result


@pytest.fixture(scope="session")
def login(HTTPRequestKeyword):
    def _function() -> Result:
        url = "http://127.0.0.1:5000/login"
        headers = {"Content-Type": "application/json"}
        body = {"username": "dongfanger", "password": "123456"}
        ro = HTTPRequestKeyword("post", url=url, headers=headers, json=body)
        response = ro.response
        assert response.status_code < 400
        ro = Result()
        ro.data = {"Content-Type": "application/json", "Cookie": f"{response.json()['Cookie']}"}
        return ro

    return _function
mysql_execute

使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def test(mysql_execute):
    sql = "select 1 from dual"
    ro = mysql_execute(sql)
    cursor = ro.cursor
    column_names = [desc[0] for desc in cursor.description]
    rows = cursor.fetchall()
    for row in rows:
        print(row)
        print(row[column_names.index("1")])  # get by column name

定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import pytest

from tep.libraries.DB import DB
from tep.libraries.Result import Result


@pytest.fixture(scope="session")
def mysql_execute(DbcKeyword):
    ro = DbcKeyword(host="127.0.0.1", port=3306, user="root", password="12345678", database="sys")
    conn = ro.conn

    def _function(sql: str) -> Result:
        cursor = conn.cursor()
        DB.pymysql_execute(conn, cursor, sql)
        ro = Result()
        ro.cursor = cursor
        return ro

    yield _function
    conn.close()  # After test, close connection

自定义关键字

关键字本质上是pytest fixture,使用@pytest.fixture装饰器即可定义。

为了规范和统一,建议采用以下原则:

  1. 自定义关键字使用小写字母加下划线命名,跟tep内置关键字区分
  2. 定义一个内部函数,返回函数名
  3. 内部函数返回Result对象

tep框架除了conftest.py定义的fixture,也能识别fixture目录下以fixture_开头的文件中,定义的fixture,并自动加载,建议把自定义关键字都放在fixture目录下。

基本结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import pytest

from tep.libraries.Result import Result


@pytest.fixture(scope="session")  # 固定
def keyword_name(other_keyword):  # 关键字命名,可以引用其他关键字
    def _function(param) -> Result:  # 内部函数,定义参数
        # 编写逻辑代码
        ro = Result()
        ro.data = ""  # 将数据存入Result对象
        return ro  # 返回Result对象

    return _function  # 将内部函数返回,使用时就能像函数一样调用

创建虚拟环境

安装时,MAC用户可以创建虚拟环境并激活:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
python3 -m venv venv
source venv/bin/activate

创建项目时,带上-venv参数,可创建单个项目的Python虚拟环境,并在该项目的虚拟环境中安装tep:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tep -s demo -venv

三方库

tep用到了很多三方库,可以学习和使用,以更好使用框架:

pytest、requests、jsonpath、pymysql、pytest-xdist、loguru、faker等。

实用案例

场景用例

登录,搜索商家,添加购物车,下单,支付:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def test(HTTPRequestKeyword, BodyKeyword, login):
    ro = login()
    var = {"domain": "http://127.0.0.1:5000", "headers": ro.data}

    url = var["domain"] + "/searchSku" + "?skuName=book"
    ro = HTTPRequestKeyword("get", url=url, headers=var["headers"])
    assert ro.response.status_code < 400
    sku_id = ro.response.jsonpath("$.skuId")
    sku_price = ro.response.jsonpath("$.price")

    url = var["domain"] + "/addCart"
    body = r"""{"skuId":1,"skuNum":2}"""
    ro = BodyKeyword(body, {"$.skuId": sku_id})
    body = ro.data
    ro = HTTPRequestKeyword("post", url=url, headers=var["headers"], json=body)
    assert ro.response.status_code < 400
    sku_num = ro.response.jsonpath("$.skuNum")
    total_price = ro.response.jsonpath("$.totalPrice")

    url = var["domain"] + "/order"
    body = r"""{"skuId":1,"price":2,"skuNum":3,"totalPrice":4}"""
    ro = BodyKeyword(body, {"$.skuId": sku_id, "$.price": sku_price, "$.skuNum": sku_num, "$.totalPrice": total_price})
    body = ro.data
    ro = HTTPRequestKeyword("post", url=url, headers=var["headers"], json=body)
    assert ro.response.status_code < 400
    order_id = ro.response.jsonpath("$.orderId")

    url = var["domain"] + "/pay"
    body = r"""{"orderId":1,"payAmount":"0.2"}"""
    ro = BodyKeyword(body, {"$.orderId": order_id})
    body = ro.data
    ro = HTTPRequestKeyword("post", url=url, headers=var["headers"], json=body)
    assert ro.response.status_code < 400
    assert ro.response.jsonpath("$.success") == "true"

该用例很好的展示了一个文件写用例,按段落,分步骤,编写的思想。

启动mock服务,位于源码tests/scripts/mock.py,可以运行此条用例成功。

仅登录一次

单进程串行:

login自定义关键字的scope="session"表示整个测试阶段都只执行一次登录。共有这些维度:session、package、module、class、function,如果设置为function则表示每次函数都要登录,其他同理。

多进程并行:

通过pytest-xdist可以实现多进程并行执行用例,为了保证全局只执行一次登录,可以自定义关键字login_xdist

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import json

import pytest
from filelock import FileLock

from tep.libraries.Result import Result


@pytest.fixture(scope="session")
def login_xdist(HTTPRequestKeyword, tmp_path_factory, worker_id):
    """
    Xdist is used in a distributed manner, and this login will only be executed globally once throughout the entire runtime
    Reference: https://pytest-xdist.readthedocs.io/en/latest/how-to.html#making-session-scoped-fixtures-execute-only-once
    """

    def _login():
        url = "http://127.0.0.1:5000/login"
        headers = {"Content-Type": "application/json"}
        body = {"username": "dongfanger", "password": "123456"}
        ro = HTTPRequestKeyword("post", url=url, headers=headers, json=body)
        response = ro.response
        assert response.status_code < 400
        ro = Result()
        ro.data = {"Content-Type": "application/json", "Cookie": f"{response.json()['Cookie']}"}
        return ro

    if worker_id == "master":
        # not executing in with multiple workers, just produce the data and let
        # pytest's fixture caching do its job
        return _login

    # get the temp directory shared by all workers
    root_tmp_dir = tmp_path_factory.getbasetemp().parent

    fn = root_tmp_dir / "data.json"
    with FileLock(str(fn) + ".lock"):
        if fn.is_file():
            _function = json.loads(fn.read_text())
        else:
            _function = _login
            fn.write_text(json.dumps(_function))
    return _function

实用技巧

Python代码格式化

快捷键:

PyCharm格式化代码不换行

默认120字符换行,根据显示屏宽度调整:

typing语法提示

给变量通过: Type指定类型后,在使用时输入.就能被PyCharm识别从而获得语法提示:

版本升级

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install -U tep

tep做了向下兼容,请放心升级,如果升级后出现不兼容问题,请联系作者。

更新日志

V2.0.0 tep关键字驱动框架

V1.0.0 tep小工具完整教程

V0.2.3 tep小工具首次开源

源码地址

如果对您有所帮助,请帮忙给开源项目点个Star吧,感谢您的支持!

https://github.com/dongfanger/tep

答疑解惑

  • 怎么向其他人介绍tep框架? 我发现了一个框架,关键字驱动的,只在一个文件里面就能把一条接口自动化用例写完。
  • 不懂代码能使用tep框架吗? 不能。学嘛,简单入门就能用,Python这么流行,学起来。
  • conftest.py无法识别? pytest7.4.0版本更新,默认只有在conftest.py相同目录执行pytest命令才能识别,如果是在子目录执行pytest则无法识别,要么显示指定--confcutdir目录位置到conftest.py所在目录,要么添加空的pytest.ini配置文件。
  • 向下兼容的分层机制怎么做的? 在tep.keywords.api做了一个适配层,暴露给用户的入参为*args, **kwargs,出参为Result对象,确保后续升级无论怎么变动入参和出参,对老项目是无感知的。

参考资料: 《测试开发刚哥电子书》https://dongfanger.gitee.io/blog/ 电子书全部由刚哥原创,包含了大量技术文章,包含Python语言、pytest测试框架、teprunner测试平台等。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
瑞幸点燃导火索,兄弟公司神州租车迎大变局
6月1日早间,神州租车有限公司(神州租车,00699.HK)公告称,董事会已获大股东神州优车告知,神州优车已于5月31日与北京汽车集团有限公司(北汽集团)订立一份无法律约束力的战略合作协议。伴随着这份协议达成,此前与华平资本的收购计划也宣告终结。
刘旷
2020/06/02
3280
瑞幸点燃导火索,兄弟公司神州租车迎大变局
可以跟风不看好瑞幸,但真该相信浑水这份方法论偏差的报告吗?
能在疫情的信息海洋中冒出头,一度成为业界关注焦点的东西不多,浑水做空瑞幸咖啡算是其中之一。
曾响铃
2020/02/21
3280
可以跟风不看好瑞幸,但真该相信浑水这份方法论偏差的报告吗?
星巴克二股东为何投资其死敌瑞幸?
2018年5月,“咖啡新物种”瑞幸发布致星巴克的公开信,呼吁给行业一个公平竞争的机会,让中国消费者有更多选择,这被视作是瑞幸与星巴克的“矛盾”公开化,两者的竞争围绕供应商和消费者同步展开。
罗超频道
2019/05/07
7650
星巴克二股东为何投资其死敌瑞幸?
瑞幸咖啡“小鹿茶”独立并推合伙人模式,深析茶饮新零售投资价值
零售资本论分析师获悉,瑞幸咖啡今日(9月3日)召开媒体沟通会,宣布旗下子品牌“小鹿茶”独立运营, 并聘请人气明星肖战担任小鹿茶品牌形象代言人,同时,推出行业首创的新零售运营合伙人模式,面向全国招募运营合伙人。
庄帅
2019/09/04
4660
瑞幸咖啡“小鹿茶”独立并推合伙人模式,深析茶饮新零售投资价值
瑞幸咖啡为何能逆风翻盘?
近日,2022年一季度的财报吸引了大家的关注,瑞幸咖啡2022年一季度的净营收达到了24亿元,同比增长了89.5%,上演了逆袭飘红的翻身大戏。根据往年的经验,一季度是传统咖啡行业的淡季,再加上疫情的催化,很多茶饮企业甚至是亏损关停的,在市场一片哀鸿遍野中,经历了造假“黑历史”的瑞幸咖啡,是如何在这么短的时间内从退市到逆流而上的呢?
博阳SCRM系统
2022/08/22
5590
瑞幸咖啡为何能逆风翻盘?
蜜雪冰城、茶颜悦色“卷”向咖啡赛道
一年一度的“双11”电商节战报,揭示了各行各业的品牌热度,今年多个咖啡品牌赫然登上爆火品牌的榜单。据了解,新锐品牌三顿半再次登顶速溶咖啡类目TOP1,截止到11月11日0点45分,今年双11累计成交额突破1亿元。无独有偶,截止11月12日零点,隅田川成为咖啡液、挂耳咖啡细分类目的TOP1。双11期间总销量达2370万,同比增长430%。
刘旷
2022/11/18
3870
瑞幸瞄准蜜雪冰城?
资料显示,本次招募计划面向安徽、河南、黑龙江、吉林、辽宁、内蒙古、山东、山西、陕西9省共41个城市开放。据了解,上述41个城市都属于已有加盟门店的城市,但这些城市共同的特点是加盟门店的数量并不密集,门店数分布在1-8家不等。
用户8049510
2022/12/14
3410
美股互联网IPO集散地,正在成为过去式
如果说近日最大的新闻,莫过于滴滴这场生死局了。6月30日,国内网约车巨头滴滴在纽交所低调上市,本应是皆大欢喜的行为,结果上市不到两天,滴滴旗下的多款APP就因涉及用户隐私安全问题已经从应用商店下架。
刘旷
2021/07/16
2410
美股互联网IPO集散地,正在成为过去式
LOHO、瑞幸、喜茶们如何“围剿”老品牌?
2018年是中国互联网行业从消费互联网进入产业互联网的分水岭,也是中国新经济崛起的元年。新老品牌势力转换开始,宜家、无印良品、星巴克等老品牌在中国市场无不感受到了一股被“围剿”的压力,这背后是越来越多中国本土的新锐的新零售品牌的崛起,日前召开的36kr WISE大会就验证了这样的趋势。
罗超频道
2018/12/21
4540
瑞幸咖啡用户运营的秘诀是什么?普通用户通过数据分析也能得到答案!
在快速发展的数字经济时代,BI已成为企业决策过程中不可或缺的工具。通过高效地收集、处理和分析海量数据,BI技术赋予企业洞察市场动态、优化运营策略、提升客户体验的能力。与人工智能、大数据和云计算的进一步融合,BI的应用范围和深度也在不断扩展,从而推动企业在竞争激烈的市场中保持领先。
数据猿
2023/12/26
8860
瑞幸咖啡用户运营的秘诀是什么?普通用户通过数据分析也能得到答案!
星巴克,廉颇老矣?
中国的茶文化起源于神农时代,经过几千年文化的熏陶,中国茶饮市场发展很是繁荣。与咖啡相比,由于进入中国市场较晚,也并未形成像茶饮一样的消费惯性和文化底蕴,咖啡一直以来都是“小资”生活的标配。
刘旷
2021/08/05
3650
星巴克,廉颇老矣?
做空瑞幸咖啡,做空中国互联网
席卷整个互联网行业的洗牌依然在持续,只不过现在洗牌的范围更广了,从一般的互联网企业延伸到了业已上市的互联网企业。对于中小型的互联网企业,这场洗牌主要是基于市场内部的,对于头部的互联网企业来讲,这场洗牌主要是基于资本市场的。我们看到了瑞幸咖啡的爆雷,爱奇艺、好未来等互联网公司陆续传出的被做空的传闻,正是这种现象的直接表现。
孟永辉
2020/04/10
3210
做空瑞幸咖啡,做空中国互联网
爱奇艺接连“踩雷”,2020年躲不开的水逆期?
4月7日晚,做空机构Wolfpack Research发布了一份针对爱奇艺的调查报告,指出爱奇艺存在严重的财务数据作假和用户数据作假问题。第二天开盘,空头继续追杀爱奇艺,股价跌幅一度超过8个点。
刘旷
2020/04/09
2410
爱奇艺接连“踩雷”,2020年躲不开的水逆期?
当我们在谈论瑞幸咖啡的时候,我们谈论什么?
一个成立48年的咖啡巨头竟然被问到是否有可能被一个乳臭未干的新入局者超越,年初,路透社记者的这个提问让星巴克的CEO始料不及。但是瑞幸咖啡的破坏性创新更是让这家咖啡巨头措手不及,给了它重重的一拳,中国咖啡市场的格局也正因此被改变。
曾响铃
2019/04/25
8740
当我们在谈论瑞幸咖啡的时候,我们谈论什么?
新茶饮加速“去泡沫”
过去7年新茶饮领域从无到有诞生了一大批行业龙头,其中高端市场被喜茶、奈雪的茶等品牌所占据,而中低端市场则诞生了茶颜悦色、茶百道以及蜜雪冰城等品牌企业。近两年随着新茶饮市场的持续升温,新茶饮赛道逐渐站上了行业风口,头中腰部的玩家也都获得了各路资本方的融资,行业发展如火如荼。
金融外参
2022/02/21
3300
奈雪的茶迫不及待奔赴IPO
如今,奶茶已成为年轻群体的常态消费产品之一,并且承载了他们一定的社交需求,逐渐渗透到了办公室社交、亲友聚会等消费场景。而随着消费场景的扩大,奶茶这个生意也越来越红火,逐渐孕育出了蜜雪冰城、喜茶等多家估值上百亿的企业。
金融外参
2021/06/15
3180
奈雪的茶迫不及待奔赴IPO
固德威:光伏逆变器全球前十,却难掩经营窘境
然而不论锂电储能亦或是光伏储能,有一个核心部件难以绕开,便是逆变器,尤其是光伏逆变器。
用户8049510
2023/01/11
3680
逆势扩张的首旅如家
说到受疫情影响最大的行业,便不得不提酒旅行业了。2020年对于酒旅行业从业者来将是极其特殊的一年,持续了几乎一整年的疫情让酒店旅游企业集体受挫。近期,酒旅类上市公司的财报陆续发布,大量企业的营收下滑,作为国内酒店三巨头之一的首旅如家也不例外。
用户6173838
2021/04/30
3210
新零售凶猛!瑞幸B轮融资估值翻倍,背后是同城物流的暗战
双12是主打新零售场景的购物节,不论是天猫、京东等电商平台,还是每日优鲜、盒马鲜生等新零售物种都展开了轰轰烈烈的促销活动。
罗超频道
2019/01/08
4220
海底捞的2020年报:一边自救,一边扩张
众所周知,餐饮行业一直是一个利润较高的行业,火锅更是餐饮消费中的一项大头。作为行业中佼佼者的海底捞,近年来也在不断发展。不但广大消费者对其无比青睐,其创始人张勇夫妇更是凭此问鼎了新一届新加坡首富。然而自疫情开始,海底捞的日子并不太好过。
刘旷
2021/03/04
3650
推荐阅读
相关推荐
瑞幸点燃导火索,兄弟公司神州租车迎大变局
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验