Cloud Code Functions
클라우드 코드 단위 테스트 작성 및 실행 방법
21 분
클라우드 코드 기능을 통해 단위 테스트를 만드는 방법 소개 이 섹션에서는 https //github com/ampme/parse server test runner 라이브러리를 사용하여 로컬에서 함수의 작동 및 테스트를 확인할 수 있습니다 전제 조건 이 튜토리얼을 완료하려면 다음이 필요합니다 단위 테스트를 적용하기 위해 node js가 설치된 로컬 환경 터미널에서 node js를 성공적으로 설치하려면 https //nodejs org/en/download/package manager/ 을 따르세요 back4app에서 생성된 앱 back4app에서 앱을 만드는 방법을 배우려면 https //www back4app com/docs/get started/new parse app 을 따르세요 프로젝트에 구성된 back4app 명령줄 프로젝트에 대한 클라우드 코드를 설정하는 방법을 배우려면 https //www back4app com/docs/local development/parse cli 을 따르세요 우선, 단위 테스트에 대해 이야기해 보겠습니다! 개발자들이 다양한 의도를 가지고 함수를 작성하기 시작할 때, 소프트웨어 커뮤니티에서 분명한 주요 포인트는 생성된 코드를 테스트하기 위한 가상의 시나리오의 적용입니다 단위 테스트 절차를 수행하는 것은 코드의 일부를 테스트할 수 있게 해주므로, 주요 코드가 손상되지 않고 온전하게 유지되도록 보장합니다 그럼 간단한 실용적인 예는 어떨까요? 완전한 문장으로 작업자의 이름, 직위 및 회사를 보여주는 함수를 작성해야 한다고 가정해 보겠습니다 다음 입력 항목을 가져오기 위해 함수를 작성해야 합니다 회사 직위 작업자 이름 간단한 테스트를 완료하는 단계 터미널에서 먼저 디렉토리를 만들고 테스트 앱(package json)을 구성하겠습니다 다음 명령어를 사용하세요 $ mkdir unit test sample && cd unit test sample $ npm init 힌트 npm init npm init 명령어를 사용하면 package json 파일을 생성할 수 있습니다 이 명령어는 가장 일반적인 항목만 포함하고 합리적인 기본값을 추측하려고 합니다 이 때문에 코드가 작동하는 데 필요한 종속성을 제공할 것입니다 “package json”의 결과는 아래 예와 비슷할 것입니다 { "name" "yourfoldername", "version" "1 0 0", "description" "just a unit test with using a simple function ", "main" "index js", "scripts" { "test" "echo \\"error no test specified\\" && exit 1" }, "repository" { "type" "git", "url" "" }, "author" "your name", "license" "isc", "bugs" { "url" "{url}/issues" }, "homepage" "" } 이제 아래 명령어를 사용하여 파일(index js)을 생성해 보겠습니다 /unit test sample$ touch index js 이제 이전에 생성한 파일에 아래 코드를 삽입할 것이며, 이 함수는 이 테스트를 코드로 보여줄 수 있는 예제를 삽입할 것입니다 1 // index js 2 module exports = function(name, position, company) { 3 let sentence = "hi, " + name + "! you are " + position + " in " + company + " company "; 4 return sentence; 5 }; nodejs에서 모듈은 관련 코드를 단일 코드 단위로 캡슐화하며, module exports ,를 사용하면 다른 파일에서 활용할 수 있는 캡슐화된 코드가 증가합니다 0/ 테스트해 보겠습니다 마지막으로, 터미널에서 작업할 수 있습니다 /unit test sample$ node \> var moduleback4app = require(' /index js'); undefined \> moduleback4app("jonathan", "developer", "back4app") 안녕하세요, jonathan! 당신은 developer로 back4app 회사에 있습니다 힌트 require() require() 함수를 사용하면 모듈을 가져오고 내보낼 수 있으며, 위의 경우에는 이 함수를 사용하여 애플리케이션 내에서 파일을 요구하고 있습니다 parse를 사용하여 내 함수를 테스트할 수 있나요? 물론입니다 테스트 매개변수로 회사 직원의 정보를 제어하는 백엔드를 생성할 것입니다 클래스를 다음과 같이 구조화해 보겠습니다 parse user (직원 참조) 사용자 이름, 이메일, 비밀번호 (필수) user 속성에 대한 추가 정보를 얻으려면 http //docs parseplatform org/js/guide/#users 가이드를 자세히 살펴보는 것을 권장합니다 infoemployee 직위 부서 근무 교대 userid (포인터) 1 우리의 최종 구조 이해하기 시작해봅시다! 우리는 https //www back4app com/docs/cloud code functions/docs parseplatform org/js/guide/ 를 함수 개발의 매개변수로 사용할 것입니다 먼저, command line interface를 사용하여 설정을 완료한 후 https //www back4app com/docs/cloud code functions/unit tests#content prerequisites ), 우리는 파일의 최종 구조와 함께 어떻게 작동하는지 이해할 것입니다 ├──back4appproject │ ├── cloud │ │ ├── functions js │ │ ├── main js │ ├── public │ ├── package json │ ├── index js │ ├── node modules │ ├── src │ │ ├── jasmine js 알림 cloud code에 파일을 업로드할 때, command line interface(참조 https //www back4app com/docs/cloud code functions/unit tests#content prerequisites )는 다른 파일을 무시하고 public 및 cloud 폴더에 있는 파일만 업로드합니다 2 함수 작성하기 command line interface를 위한 환경을 구성한 후, 우리는 직원 등록 프로세스를 구축하고 추가 정보를 저장하기 위한 함수를 작성할 것입니다 코드를 리팩토링하여 main js 파일에서 이러한 함수를 main에 가져올 것입니다, 다음과 같이 1 //in 1cloud/main js 2 3 var cloudfunctions = require(" /functions"); 4 5 / it's necessary to insert the parse instance in our code, 6 because at local context not is referenced / 7 8 parse cloud define("registeruser", cloudfunctions registeruser(parse)); 9 10 parse cloud beforesave("infoemployee", infoemployee infoemployee(parse)); 아이디어는 클라우드 인터페이스에서 기능을 분리하여 http 요청을 비효율적으로 보내지 않고도 테스트할 수 있도록 하는 것입니다 이는 테스트 스위트를 만들면서 많은 의미가 있을 것입니다 parse server 3 x 1 //in cloud/functions js 2 3 module exports registeruser = function(parse){ 4 return async(request) =>{ 5 let params = request params; //parameters received 6 let infoemployee = parse object extend("infoemployee"); //store information 7 8 let usercreated = new parse user({ 9 "email" params email, 10 "username" params username, 11 "password" params password 12 }) 13 14 //save relation 15 try { 16 let result = await usercreated save(); 17 18 let information = new infoemployee({ 19 "position" params position, 20 "department" params department, 21 "workshift" params shift, 22 "user" result 23 }); 24 25 return information save(); 26 } catch (e) { 27 return e message; 28 } 29 } 30 } 31 32 module exports infoemployee = function(parse){ 33 return async (request) =>{ 34 let req = request object; 35 36 if (!req get("position") || !req get("department") || !req get("workshift")) { 37 throw new error("missing params! the required parameters are position, department workshift"); 38 } else { 39 return; 40 } 41 } 42 } parse server 2 x 1 //in cloud/functions js 2 3 module exports registeruser = function(parse){ 4 return function (request, response){ 5 var params = request params; //parameters received 6 7 var infoemployee = parse object extend("infoemployee"); //store information 8 9 var usercreated = new parse user({ 10 "email" params email, 11 "username" params username, 12 "password" params password 13 }) 14 15 //save relation 16 usercreated save() then((updateduser) => { 17 var information = new infoemployee({ 18 "position" params position, 19 "department" params department, 20 "workshift" params shift, 21 "user" updateduser 22 }); 23 return information save(); 24 }) then((info) => response success(info)) 25 catch((e) => { 26 response error(e message); 27 }) 28 } 29 } 30 31 module exports infoemployee = function(parse){ 32 return function (request, response){ 33 var req = request object; 34 35 if (!req get("position") || !req get("department") || !req get("workshift")) { 36 response error("missing params! the required parameters are position, department workshift"); 37 } else { 38 response success(); 39 } 40 } 41 } 3 위 코드를 테스트하기 위한 환경 설정! 우리의 테스트 스위트에서는 https //jasmine github io/ , 매우 인기 있는 javascript 테스트 프레임워크를 사용할 것입니다 그러나 지금까지의 코드는 우리의 테스트와 완전히 무관하므로, 원하는 프레임워크나 플랫폼을 사용할 수 있습니다 개발 종속성 설치 jasmine을 전역적으로 설치하고 아래 명령어를 사용합시다 /back4appproject$ sudo npm install g jasmine /back4appproject$ jasmine 시드 48094로 무작위화됨 시작됨 사양을 찾을 수 없음 0 002초 만에 완료됨 불완전 사양을 찾을 수 없음 4 폴더에서 parse server 테스트 러너 구성하기 back4app의 프로젝트 클라우드 폴더에 구현된 우리의 방법을 사용하여, 이 상호작용을 구성할 node js 프로젝트에 새로운 파일을 생성할 것입니다 /back4appprojectsrc$ touch index js /back4appproject$ mkdir src && cd src /back4appproject/src$ touch jasmine js 이제 위에서 생성한 파일을 아래에 표시된 코드로 구성하겠습니다 index js 1 const promise = require('bluebird'); 2 const express = require('express'); 3 const http = require('http'); 4 const {mongoclient} = require('mongodb'); 5 const {parseserver} = require('parse server'); 6 7 const mongodbrunnerstart = require('mongodb runner/mocha/before') bind({ 8 timeout() { 9 }, 10 slow() { 11 }, 12 }); 13 const mongodbrunnerstop = require('mongodb runner/mocha/after'); 14 15 const startdb = () => ( 16 new promise((done, reject) => { 17 done fail = reject; 18 mongodbrunnerstart(done); 19 }) 20 ); 21 22 const stopdb = () => ( 23 new promise((done, reject) => { 24 done fail = reject; 25 mongodbrunnerstop(done); 26 }) 27 ); 28 29 const connectdb = (databaseuri) => new promise((resolve, reject) => { 30 mongoclient connect(databaseuri, (err, db) => { 31 if (err) { 32 reject(err); 33 } else { 34 resolve(db); 35 } 36 }); 37 }); 38 39 let parseserverstate = {}; 40 41 const dropdb = () => { 42 const {mongoconnection} = parseserverstate; 43 return mongoconnection dropdatabaseasync(); 44 }; 45 46 / 47 starts the parseserver idropdatabaseasyncnstance 48 @param {object} parseserveroptions used for creating the `parseserver` 49 @return {promise} runner state 50 / 51 function startparseserver(parseserveroptions = {}) { 52 const mongodbport = process env mongodb port || 27017; 53 const { 54 databasename = 'parse test', 55 databaseuri = 'mongodb //localhost ${mongodbport}/${databasename}', 56 masterkey = 'test', 57 javascriptkey = 'test', 58 appid = 'test', 59 60 port = 30001, 61 mountpath = '/1', 62 serverurl = 'http //localhost ${port}${mountpath}', 63 } = parseserveroptions; 64 65 return startdb() 66 then(() => connectdb(databaseuri)) 67 then((mongoconnection) => { 68 parseserveroptions = object assign({ 69 masterkey, javascriptkey, appid, 70 serverurl, 71 databaseuri, 72 silent process env verbose !== '1', 73 }, parseserveroptions); 74 const app = express(); 75 const parseserver = new parseserver(parseserveroptions); 76 77 app use(mountpath, parseserver); 78 79 const httpserver = http createserver(app); 80 81 promise promisifyall(httpserver); 82 promise promisifyall(mongoconnection); 83 84 return httpserver listenasync(port) 85 then(() => object assign(parseserverstate, { 86 parseserver, 87 httpserver, 88 mongoconnection, 89 expressapp app, 90 parseserveroptions, 91 })); 92 }); 93 } 94 95 / 96 stops the parseserver instance 97 @return {promise} 98 / 99 function stopparseserver() { 100 const {httpserver} = parseserverstate; 101 return httpserver closeasync() 102 then(stopdb) 103 then(() => parseserverstate = {}); 104 } 105 106 module exports = { 107 dropdb, 108 startparseserver, 109 stopparseserver, 110 parseserverstate, 111 }; jasmine js 1 const { startparseserver, stopparseserver, dropdb } = require('parse server test runner'); 2 3 describe('registeruser', () => { 4 beforeall((done) => { 5 const appid = 'test'; 6 const masterkey = 'test'; 7 const javascriptkey = 'test'; 8 9 startparseserver({ appid, masterkey, javascriptkey }) 10 then(() => { 11 parse initialize(appid, masterkey, javascriptkey); 12 parse serverurl = 'http //localhost 30001/1'; 13 }) 14 then(done) catch(done fail); 15 }, 300 60 2); 16 17 afterall((done) => { 18 stopparseserver() 19 then(done) catch(done fail); 20 }); 21 22 beforeeach((done) => { 23 dropdb() 24 then(done) catch(done fail); 25 }); 26 27 it('should work', (done) => { 28 const q = new parse query(' user') 29 q limit(5) 30 find({ usemasterkey true }) 31 then(console log) 32 then(done) catch(done fail); 33 }); 34 }); 마지막 단계는 다음 명령어를 사용하여 package json을 구성하는 것입니다 $ npm init $ npm init 루트 디렉토리에서 (아래 파일은 필요한 모듈의 예일 뿐입니다) 1 { 2 "name" "back4approject", 3 "version" "1 0 0", 4 "description" "back4app guide using for reference the parse server test runner", 5 "main" "index js", 6 "engines" { 7 "node" ">=6" 8 }, 9 "repository" { 10 "type" "", 11 "url" "" 12 }, 13 "keywords" \[ 14 "parse", 15 "parse server", 16 "testing", 17 "tests" 18 ], 19 "author" "", 20 "license" "isc", 21 "dependencies" { 22 "bluebird" "^3 5 0", 23 "express" "latest", 24 "mongodb" "^2 2 30", 25 "mongodb runner" "^3 5 0", 26 "parse" "^1 10 0", 27 "parse server" "^2 5 3", 28 "parse server test runner" "^1 0 0" 29 } 30 } 이제 우리는 https //www back4app com/docs/cloud code functions/unit tests#content structure 단계에서 설명한 구조에 접근했는지 확인할 것입니다 ) 5 터미널로 돌아가기 로컬 테스트를 구성하기 시작하겠습니다 이를 위해 아래 명령어를 따라 코드를 프로그래밍 방식으로 설정하여 테스트 목적으로 사용할 것입니다 /back4appproject$ # package json이 있는 동일한 디렉토리에서 /back4appproject$ npm install 성공적으로 설치한 후, 설명된 명령어로 로컬에서 단위 테스트를 확인하고 다음과 같은 결과를 받을 수 있습니다 /back4appproject$ jasmine src/jasmine js 시드 79055로 무작위화됨 시작됨 ✔ mongodb 3 6 5 다운로드됨 \[] 1 스펙, 0 실패 19 983초 만에 완료됨 시드 79055로 무작위화됨 (jasmine random=true seed=79055) 멋져요, 준비 완료! 위에 설명된 가이드를 통해 parse server test runner와 back4app을 위한 cloud code로 개발한 함수와 함께 작업할 수 있습니다