json格式校验并显示错误_使用postman做自动化接口校验

要想实现接口的自动化测试,需要以下几个步骤:

自动登录

首先点击postman左上角的new按钮,创建一个collection,在pre-request-scripts标签下,给整个collection创建一个公用规则

642632d09b913ad15ff0ca340fb396fc.png

05a1e7575d030d5b6e34be0a3f709981.png

编写登录脚本

pre-request-scripts在请求发送前执行的脚本,在整个集合期间只会执行一次

在集合变量(参考上图)中添加对应的用户名和密码

//获取集合
const { host, username, password } = pm.collectionVariables.toObject();

使用pm.sendRequest方法发送一个ajax请求,将请求成功的结果的token值存到环境变量中。

const data = res.json();
pm.environment.set("token", data.data["X-Access-Token"]);  

完整代码如下:

const {// host,yapiToken,yapiHost,variable_key,token,catid,CooperationPlatformId
} = pm.variables.toObject();const { host, username, password } = pm.collectionVariables.toObject();
const echoPostRequest = {url: `${host}/api/login`,method: 'POST',header: 'Content-Type: application/json;charset=UTF-8',body: {mode: 'raw',raw: JSON.stringify({ username, password})}
};
//使用pm.sendRequest方法发送一个ajax请求,
if(!token){pm.sendRequest(echoPostRequest, function (err, res) {console.log(err ? err : res.json());const data = res.json();pm.environment.set("token", data.data["X-Access-Token"]);  });    
}

f064b84d663d44908af9d7b86b1577c6.png

yapi,去哪网出的开源的可视化接口管理平台,推荐部署到公司服务器,也可以直接使用官方的。

YApi-高效、易用、功能强大的可视化接口管理平台​yapi.demo.qunar.com

63442d5b4ad59ac8fe8fead86b19590b.png

schema格式的约束文件,值得推荐的地方就是对mockjs语法支持的很好。

{"type": "object","title": "empty object","properties": {"data": {"type": "object","properties": {"name": {"type": "string","mock": {"mock": "@string"}}},"required": ["name"]},"code": {"type": "string","mock": {"mock": "@natural"}},"msg": {"type": "string","mock": {"mock": "@string"}}},"required": ["data","code","msg"]
}
开放Api​hellosean1025.github.io

获取接口的schema文件

yapi的开发api很方便的获取接口相关的信息。

//生成分类下接口列表的map对象
const genCatInterfaceListMap = function (catid) {return new Promise(function (resolve, reject) {const url = `${yapiHost}/api/interface/list_cat?token=${yapiToken}&catid=${catid}&limit=100`;pm.sendRequest(url, function(err, res){if(err){console.log("err: ", err)}else{var data = res.json();var list = data.data.list;var catInterfaceListMap = list.reduce((acc, item) => {var key = item.path.slice(1).split("/").join("_");acc[key] = item._id;return acc;}, {})resolve(catInterfaceListMap);}})});
};

获取指定分类下的接口列表,并存到集合变量中。

genCatInterfaceListMap(catid).then((newMap) => {let catInterfaceListMap =  pm.collectionVariables.get("catInterfaceListMap") || {};pm.collectionVariables.set("catInterfaceListMap", Object.assign({}, catInterfaceListMap, newMap));
});genCatInterfaceListMap(CooperationPlatformId).then((newMap) => {let catInterfaceListMap =  pm.collectionVariables.get("catInterfaceListMap") || {};pm.collectionVariables.set("catInterfaceListMap", Object.assign({}, catInterfaceListMap, newMap));
})

关键环节来了从yapi获取接口的schema,并验证格式

//验证数据格式测试用例。
pm.test("数据格式正确", () => {var valid = validate(pm.response.json());if(!valid){console.log("validate.errors", validate)validate.errors.forEach(function(item){console.log(item.dataPath, ":", item.message);})}pm.expect(valid).to.be.true
})   

使用avj来做校验;

var Ajv = require('ajv');
var ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}
var validate = ajv.compile(schema);
var valid = validate(data);
if (!valid) console.log(validate.errors);

完整代码

在collection的Tests tab下,编写下面代码

//从yapi 服务上获取到了对应的schema,检验接口返回值是否匹配schema
var Ajv = require("ajv");
var ajv = new Ajv({logger: console, allErrors: true});
const { path } = pm.request.url;
const yapiToken = pm.variables.get("yapiToken")
const pathKey = path.slice(-3).join("_");
const catid293 = pm.variables.get("catid293");
const interfaceId = catid293[pathKey];console.log("path:Test", pathKey, catid293, interfaceId);
const url = `http://yapi.ops.tst-weiboyi.com/api/interface/get?token=${yapiToken}&id=${interfaceId}`;//从yapi接口中获取当前接口的schema
pm.sendRequest(url, function(err, res){if(err){console.log("err: ", err)}else{var data = res.json();var schema = JSON.parse(data.data.res_body);delete schema["$schema"];var validate = ajv.compile(schema);pm.test("数据格式正确", () => {var valid = validate(pm.response.json());if(!valid){console.log("validate.errors", validate)validate.errors.forEach(function(item){console.log(item.dataPath, ":", item.message);})}pm.expect(valid).to.be.true})    }
})

输出错误信息

还有其他方法和参数,默认validate.errors虽然是个数组,但里面默认只包含了第一条错误。具体能否输出所有不匹配字段,还待研究?

补充:

//allErrors 默认为false,只能显示一条信息
var ajv = new Ajv({logger: console, allErrors: true});
编写测试入门-带有示例​documenter.getpostman.com

使用变量作为请求参数

(function(){const data = pm.response.json();const list = data.data.list;//获取满足指定操作条件的idconst okIds = list.filter(item => item.type == 1).map(item => item.id);const passIds = list.filter(item => item.type == 2).map(item => item.id);const [ okId ] = okIds;const [ passId ] = passIdspm.collectionVariables.set("customId", okId);pm.collectionVariables.set("passId", passId);
})()

可以在下个请求中使用上个请求存储的变量

{"type":"2", "remark":"1111", "id": {{okId}}
}

9c759783ebb8c867c0bb3d4f7c7029ed.png

在body里面获取变量注意事项

pm.collectionVariables.set("ids", [1,2,3]);
//在body里面需要这样写
{"ids":{{ids}}
}

自动化批量测试

9e4ed4f4d80a1e178daf384df09b6e20.png

17b6a312358ffb01f95c0bfbbce6ef41.png

查看格式报错

在postman的控制台,可以显示所有格式错误的log

f419fc9c627a8320a6b68d559356d449.png

其他的集合测试用例

在编辑集合的弹窗里面,Tests标签下,可以编写公共测试用例,集合下的每个请求都会执行

pm.test("Status code is 200", function () {pm.response.to.have.status(200);
});pm.test('状态码为1000', () => {var d = pm.response.json();pm.expect(d.code).to.equal("1000")
})pm.test("Response time is less than 200ms", function () {pm.expect(pm.response.responseTime).to.be.below(200);
});//清除全局变量
pm.globals.unset("variable_key");pm.test("Content-Type is present", function () {pm.response.to.have.header("Content-Type");
});

编写单个请求的测试用例

在每个请求的Tests标签下,可以编写脚本,这个是请求成功后执行的代码

//获取变量
const aId = pm.collectionVariables.get("accountId");console.log("aId", aId)
//编写测试用例
pm.test(`上架成功, id: ${aId}`, () => {//将返回值转换为json对象var d = pm.response.json();//验证返回值的code值是否是1000pm.expect(d.code).to.equal("1000")
})

相关文档

pm.expect语法相关文档 chaijs BDD(想弄明白,就仔细看一遍这个文档)

BDD

The BDD styles are expect and should. Both use the same chainable language to construct assertions, but they differ in the way an assertion is initially constructed. Check out the Style Guide for a comparison.

API Reference

Language Chains
The following are provided as chainable getters to improve the readability of your assertions.Chains

  • to
  • be
  • been
  • is
  • that
  • which
  • and
  • has
  • have
  • with
  • at
  • of
  • same
  • but
  • does
  • still

.not

Negates all assertions that follow in the chain.

expect(function () {}).to.not.throw();
expect({a: 1}).to.not.have.property('b');
expect([1, 2]).to.be.an('array').that.does.not.include(3);

以下是文档相关内容,postman-sanbox-api-reference;(pm对象的相关属性)

在postman的沙箱内有几个作用域

优先顺序是Iteration Data<Environment<Collection<Global。四个作用域分别对应下面四个变量。

pm.variables,在 pre-request scripts中pm.variables.set("path", "/api/xxx"),在Test中可以通过pm.variables.get("path")获取到

pm.variables

pm.variables: 阅读有关VariableScope的更多信息

在Postman中,所有变量都符合特定的层次结构。当前迭代中定义的所有变量优先于当前环境中定义的变量,当前环境中的变量将覆盖全局范围中定义的变量。优先顺序是Iteration Data< Environment< Collection< Global

  • pm.variables.has(variableName:String):function → Boolean:检查当前作用域中是否存在局部变量。
  • pm.variables.get(variableName:String):function → *:获取具有指定名称的局部变量的值。
  • pm.variables.toObject():function → Object:返回包含本地范围内所有变量的对象。
  • pm.variables.set(variableName:String, variableValue:String"):function → void:使用给定值设置局部变量。

还可通过pm.environment环境范围和pm.globals全局范围访问在各个范围中定义的变量。

pm.environment

pm.environment: 阅读有关VariableScope的更多信息

  • pm.environment.name:String:包含当前环境的名称。
  • pm.environment.has(variableName:String):function → Boolean:检查环境是否具有具有给定名称的变量。
  • pm.environment.get(variableName:String):function → *:获取具有给定名称的环境变量。
  • pm.environment.set(variableName:String, variableValue:String):function:使用给定的名称和值设置环境变量。
  • pm.environment.unset(variableName:String):function:删除具有指定名称的环境变量。
  • pm.environment.clear():function:清除所有当前环境变量。
  • pm.environment.toObject():function → Object:以单个对象的形式返回所有环境变量。

pm.collectionVariables

pm.collectionVariables: 阅读有关VariableScope的更多信息

  • pm.collectionVariables.has(variableName:String):function → Boolean:检查是否存在具有给定名称的集合变量。
  • pm.collectionVariables.get(variableName:String):function → *:返回具有给定名称的collection变量的值。
  • pm.collectionVariables.set(variableName:String, variableValue:String):function:设置具有给定值的集合变量。
  • pm.collectionVariables.unset(variableName:String):function:清除指定的集合变量。
  • pm.collectionVariables.clear():function:清除所有集合变量。
  • pm.collectionVariables.toObject():function → Object:以对象的形式返回变量及其值的列表。

pm.globals

pm.globals: 阅读有关VariableScope的更多信息

  • pm.globals.has(variableName:String):function → Boolean:检查是否存在具有给定名称的全局变量。
  • pm.globals.get(variableName:String):function → *:返回具有给定名称的全局变量的值。
  • pm.globals.set(variableName:String, variableValue:String):function:设置具有给定值的全局变量。
  • pm.globals.unset(variableName:String):function:清除指定的全局变量。
  • pm.globals.clear():function:清除所有全局变量。
  • pm.globals.toObject():function → Object:以对象的形式返回变量及其值的列表。

pm.request

pm.request: 阅读有关VariableScope的更多信息

request内部的对象pm表示正在为此脚本运行的请求。对于请求前脚本,这是将要发送的请求,在测试脚本中时,这是已发送请求的表示。

request 包含以以下结构存储的信息:

  • pm.request.url:Url:包含发出请求的URL。
  • pm.request.headers:HeaderList:包含当前请求的标头列表。
  • pm.request.headers.add(headerName:String):function:为当前请求添加具有指定名称的标头。
  • pm.request.headers.delete(headerName:String):function:删除具有当前请求的指定名称的标头。
  • pm.request.headers.upsert({ key: headerName:String, value: headerValue:String}):function):插入给定当前请求的标题列表的标题名称和标题值(如果标题不存在,否则将已存在的标题更新为新值)。
以下项目仅在测试脚本中可用。

pm.response

pm.response: 阅读有关响应的更多信息

在测试脚本中,该pm.response对象包含与收到的响应有关的所有信息。

响应详细信息以以下格式存储:

  • pm.response.code:Number
  • pm.response.reason():Function → String
  • pm.response.headers:HeaderList
  • pm.response.responseTime:Number
  • pm.response.text():Function → String
  • pm.response.json():Function → Object

pm.iterationData

pm.iterationData: 阅读有关VariableScope的更多信息

iterationData对象包含在收集运行期间提供的数据文件中的数据。

  • pm.iterationData.get(variableName:String):function → *:从迭代数据中返回具有指定名称的变量。
  • pm.iterationData.toObject():function → Object:将迭代数据作为对象返回。
  • pm.iterationData.addLayer(list: VariableList):function → void:将变量列表添加到迭代数据。
  • pm.iterationData.clear():function → void:清除所有数据。
  • pm.iterationData.has(variableName: string):function → boolean:检查迭代数据中是否存在具有指定名称的变量。
  • pm.iterationData.set(key: string, value: any, type: string):function → void:设置变量,为其指定值和类型。
  • pm.iterationData.syncVariablesFrom(object: {[key: string]: VariableDefinition}, track?: boolean, prune?: boolean):function → Object | Undefined:从具有指定名称的对象获取变量。
  • pm.iterationData.syncVariablesTo(object?: {[key: string]: VariableDefinition}):function → Object:将变量保存到具有指定名称的对象。
  • pm.iterationData.toJSON():function → *:将迭代数据对象转换为JSON格式。
  • pm.iterationData.unset(key: string):function → void:取消分配给指定变量的值。
  • pm.iterationData.variables():function → Object:从erationData对象返回所有变量。
  • static pm.iterationData.isVariableScope(object: any):function → boolean:检查特定变量是否在范围内。

pm.cookies

pm.cookies: 阅读有关CookieList的更多信息

cookies对象包含与请求域相关联的cookie列表。

  • pm.cookies.has(cookieName:String):Function → Boolean
    检查请求的域是否存在特定的cookie(以其名称寻址)。
  • pm.cookies.get(cookieName:String):Function → String
    获取特定cookie的值。
  • pm.cookies.toObject:Function → Object
    以对象的形式获取所有cookie及其值的副本。返回的cookie是为请求的域和路径定义的cookie。

pm.cookies.jar

  • pm.cookies.jar():Function → Object
    访问Cookie罐对象。
  • jar.set(URL:String, cookie name:String, cookie value:String, callback(error, cookie)):Function → Object
    使用Cookie名称和值设置Cookie。也可以通过在此函数中将cookie值与cookie名称相关联来直接设置cookie。
  • jar.set(URL:String, { name:String, value:String, httpOnly:Bool }, callback(error, cookie)):Function → Object
    使用PostmanCookie或其兼容对象设置cookie。
  • jar.get(URL:String, token:String, callback (error, value)):Function → Object
    从Cookie罐获取Cookie。
  • jar.getAll(URL:String, callback (error, cookies)):Function → Object
    从cookie罐中获取所有cookie。
  • jar.unset(URL:String, token:String, callback(error)):Function → Object
    取消设置Cookie。
  • jar.clear(URL:String, callback (error)):Function → Object
    清除饼干罐中的所有饼干。

pm.test

pm.test(testName:String, specFunction:Function):Function

您可以使用此功能在Pre-request ScriptTests沙箱中编写测试规范。在此函数中编写测试可以使您准确地命名测试,并且即使该函数内部存在错误,该函数也可以确保脚本的其余部分不会被阻塞。

在下面的示例测试中,我们正在检查关于响应的所有内容对我们来说都是有效的。

pm.test("response should be okay to process", function () {pm.response.to.not.be.error;pm.response.to.have.jsonBody('');pm.response.to.not.have.jsonBody('error');});

done可以将 可选的回调添加到中pm.test,以测试异步功能。

pm.test('async test', function (done) {setTimeout(() => {pm.expect(pm.response.code).to.equal(200);done();}, 1500);});
  • pm.test.index():Function → Number
    从特定位置获取总数测试。

期望值

pm.expect(assertion:*):Function → Assertion

pm.expect是一个通用的断言函数。这是ChaiJS期望的BDD库的基础。使用该库,可以很容易地编写语法易读的测试。

此功能对于处理来自response或的数据断言很有用variables。有关使用的断言测试示例pm.expect,请查看断言库示例

测试脚本中可用的响应声明API

  • pm.response.to.have.status(code:Number)
  • pm.response.to.have.status(reason:String)
  • pm.response.to.have.header(key:String)
  • pm.response.to.have.header(key:String, optionalValue:String)
  • pm.response.to.have.body()
  • pm.response.to.have.body(optionalValue:String)
  • pm.response.to.have.body(optionalValue:RegExp)
  • pm.response.to.have.jsonBody()
  • pm.response.to.have.jsonBody(optionalExpectEqual:Object)
  • pm.response.to.have.jsonBody(optionalExpectPath:String)
  • pm.response.to.have.jsonBody(optionalExpectPath:String, optionalValue:*)
  • pm.response.to.have.jsonSchema(schema:Object)
  • pm.response.to.have.jsonSchema(schema:Object, ajvOptions:Object)

pm.to.be. *

通过pm.response.to.be对象内部的属性,您可以轻松地声明一组预定义规则。

  • pm.response.to.be.info
    检查1XX状态码
  • pm.response.to.be.success
    检查2XX状态码
  • pm.response.to.be.redirection
    检查3XX状态码
  • pm.response.to.be.clientError
    检查4XX状态码
  • pm.response.to.be.serverError
    检查5XX
  • pm.response.to.be.error
    检查4XX或5XX
  • pm.response.to.be.ok
    状态码必须为200
  • pm.response.to.be.accepted
    状态码必须为202
  • pm.response.to.be.badRequest
    状态码必须为400
  • pm.response.to.be.unauthorized
    状态码必须为401
  • pm.response.to.be.forbidden
    状态码403
  • pm.response.to.be.notFound
    检查响应的状态码为404
  • pm.response.to.be.rateLimited
    检查响应状态码是否为429

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/409675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(2906):Vite 解决了 Webpack 哪些问题

随着项目的复杂度升级&#xff0c;代码规范和管理就必须要同步提升。于是&#xff0c;编程社区中提出了多种模块化规范&#xff0c;服务端选择了 CommonJS 规范&#xff0c;客户端选择 AMD 规范较多&#xff0c;但是&#xff0c;两种模块化规范也都存在一定的问题&#xff0c;都…

wpf 去除按钮点击时会画一个点线的矩形

wpf 去除按钮点击时会画一个点线的矩形 最近在研究wpf&#xff0c;啥都不懂&#xff0c;特把自己查到的有用东西&#xff0c;收集一下&#xff1a;<Pagexmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.…

tfidf算法 python_tf–idf算法解释及其python代码实现(下)

tf–idf算法python代码实现这是我写的一个tf-idf的简单实现的代码&#xff0c;我们知道tfidftf*idf&#xff0c;所以可以分别计算tf和idf值在相乘&#xff0c;首先我们创建一个简单的语料库&#xff0c;作为例子&#xff0c;只有四句话&#xff0c;每句表示一个文档copus[我正在…

powerbuilder提示不是下拉窗口_为什么过去状态管理不是问题?

2-tier 架构远古时期&#xff0c;状态是完全由数据库管理的。数据库提供的连接是有状态的&#xff0c;打开页面的时候开连接&#xff0c;页面上的改动直接提交到当前的数据库连接。数据库连接的状态就是页面状态。3-tier 架构后来因为互联网类型的应用的发展&#xff0c;数据库…

mysql 查询前10门课程_数据库面试题:如何查找每门课程的前3名?

看到别人的面经里有类似这样一个问题&#xff0c;我自己试了下&#xff0c;感觉做不出来。DROP TABLE IF EXISTS SC;CREATE TABLE SC (SId varchar(10) DEFAULT NULL,CId varchar(10) DEFAULT NULL,score decimal(18,1) DEFAULT NULL);INSERT INTO SC VALUES (01, 01, 80.0);IN…

Java编程程序异常处理方法

对于java异常处理你是否都掌握了呢&#xff0c;如果是&#xff0c;你是否能在下面这段代码中&#xff0c;迅速找出异常处理的六个问题吗&#xff1f; 1、OutputStreamWriter out …   2、java.sql.Connection conn …   3、try { // ⑸   4、 Statement stat conn.…

[html] img中的src加载失败时如何用默认图片来替换呢?

[html] img中的src加载失败时如何用默认图片来替换呢&#xff1f; img有onerror属性&#xff0c;加载失败时触发error事件 但是这种解决方法在error里面替换的默认图片也加载失败的时候会导致问题&#xff0c;需要注意个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端…

学完php在学python_写给PHP程序员的 Python学习指南(建议去看原文)

原文&#xff1a;https://segmentfault.com/a/1190000019710720一、背景人工智能这几年一直都比较火&#xff0c;笔者一直想去学习一番&#xff1b;因为一直是从事PHP开发工作&#xff0c;对于Python接触并不算多&#xff0c;总是在关键时候面临着 基础不牢&#xff0c;地动山摇…

mysql 实例复制_MYSQL教程MySQL 复制详解及简单实例

《MysqL教程MysqL 复制详解及简单实例》要点&#xff1a;本文介绍了MysqL教程MysqL 复制详解及简单实例&#xff0c;希望对您有用。如果有疑问&#xff0c;可以联系我们。MysqL 复制详解及简单实例主从复制技术在MysqL中被广泛使用,主要用于同步一台服务器上的数据至多台从服务…

[html] 解释下什么是CDATA?

[html] 解释下什么是CDATA&#xff1f; CDATA 指的是不由 XML 解析器进行解析的文本数据。XML 文档中的所有文本均会被解析器解析。只有 CDATA 区段中的文本会被解析器忽略。个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很…

kali字典_kali黑客系统wpscan工具扫描wordpress漏洞入侵攻击测试教程

WPScan是Kali Linux默认自带的一款漏洞扫描工具&#xff0c;它采用Ruby编写&#xff0c;能够扫描WordPress网站中的多种安全漏洞&#xff0c;其中包括主题漏洞、插件漏洞和WordPress本身的漏洞。最新版本WPScan的数据库中包含超过18000种插件漏洞和2600种主题漏洞&#xff0c;并…

局部遮罩 shade(二)

其实它和全局遮罩是一样的思想&#xff0c;只不过就要用position了 <script type"text/javascript">function shade(){var p document.getElementById("shade");p.className "d";p.style.display "block";}function shadeDis…

[html] 移动端如何禁止用户手动缩放页面?

[html] 移动端如何禁止用户手动缩放页面&#xff1f; <meta name"viewport" content"widthdevice-width,initial-scale1,maximum-scale1,minimum-scale1,user-scalableno">个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易…

python怎么填充画布_如何在kivy中用图像填充画布?

矩形设置为MyPaintWidget的大小&#xff0c;在父小部件上以默认大小绘制。如果MyPaintWidget是根小部件&#xff0c;那么设置self.size将允许它占用整个窗口空间。(请注意&#xff0c;当前结构只会在on-touch-down事件上调整画布的大小。因此&#xff0c;如果调整窗口大小&…

[html] HTML5的video怎样预加载(支持全量加载)?

[html] HTML5的video怎样预加载&#xff08;支持全量加载&#xff09;&#xff1f; preload"auto"个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

mysql df_MySQL主从复制实战

什么是主从复制使用两个或两个以上的数据库&#xff0c;一部分数据库当做主数据库&#xff0c;而另一部分数据库当做从数据库。系统在主数据库中进行写操作&#xff0c;从数据库记录在主库上所有的写操作&#xff0c;使得主从数据库的数据保持一致。一旦主数据库出现问题时&…

python logistic回归_logistic回归介绍与源码分析

1. 介绍&#xff08;由线性模型引出logistic回归&#xff09;首先介绍一下什么是线性模型呢&#xff1f;线性模型的定义如下&#xff1a;给定 个属性描述的样本 &#xff0c; 代表样本在第 个属性上的取值。线性模型的目的是学习一个函数&#xff0c;它可以通过属性的线性组合来…

[html] 列举几种多列等高布局的方法

[html] 列举几种多列等高布局的方法 1, 使用table布局 .row { display: table; }.row > * { display: table-cell; }2, 使用flex布局.row { display: flex; flex-wrap: wrap; } .row > * { display: flex; flex-direction: column; }个人简介 我是歌谣&#xff0c;欢迎…

当前标签: Entity Framework

当前标签: Entity Framework在Entity Framework中使用泛型 qouoww 2012-04-29 22:39 阅读:1937 评论:4 一步一步学Entity Framework 4.x (3) qouoww 2012-04-27 17:20 阅读:2569 评论:8 一步一步学Entity Framework 4(2) qouoww 2012-04-27 09:10 阅读:2972 评论:7 一步一步…