Tests unitaires de cloud code
Pendant ou après le développement de votre application, vous souhaiterez commencer à ajouter des tests unitaires pour votre cloud code, pour vous aider à vérifier l'état actuel de votre application.
Tout d’abord, vous allez vouloir établir votre framework de test et votre outil CI qui exécuteront les tests unitaires pour chaque version de "build" de votre application.
Disons que notre application dispose d'une entité globale qui constitue un catalogue de cafés pouvant être achetés contre des points.
COFFEE_CATALOG
{
"coffees": {
"DARK_ROAST": {
"name": "Dark Roast",
"points": {
"cost": 2500
}
},
"MOCHA": {
"name": "Mocha",
"points": {
"cost": 4000
}
}
}
}
Nous avons un script de code cloud qui permet à l'utilisateur d'acheter l'un de ces cafés, s'il a suffisamment de points.
PurchaseCoffee, un script un peu long que nous allons vouloir tester unitairement.
function PurchaseCoffee() {
var entityIndexedId = 'COFFEE_CATALOG';
var maxReturn = 2;
var globalEntityProxy = bridge.getGlobalEntityServiceProxy();
var catalog = {};
try {
var getListByIndexedIdResult = globalEntityProxy.getListByIndexedId(
entityIndexedId,
maxReturn
);
catalog = getListByIndexedIdResult.data.entityList[0].data;
if (getListByIndexedIdResult.data.entityList.length > 1) {
bridge.logWarningJson(
'Multiple catalogs exist',
getListByIndexedIdResult
);
}
} catch (e) {
bridge.logErrorJson(
'Cannot retrieve catalog',
getListByIndexedIdResult
);
throw 'Cannot retrieve catalog';
}
var currencyType = 'points';
var coffee = catalog.coffees[data.key];
var amount = coffee.points.cost;
var productProxy = bridge.getProductServiceProxy();
var consumeCurrencyResult = productProxy.consumeCurrency(
currencyType,
amount
);
// Échec de l'achat. Sortie
if (consumeCurrencyResult.status !== 200) {
if (consumeCurrencyResult.reason_code === 40385) {
return {
reason_code: 40385,
message: 'Not enough points to redeem.'
};
} else {
return consumeCurrencyResult;
}
}
try {
var entityType = 'INVENTORY';
var entityProxy = bridge.getEntityServiceProxy();
var inventory = entityProxy.getSingleton(entityType).data;
if (inventory === null || inventory.itemList === null) {
inventory = {};
inventory.itemList = [];
} else {
inventory = inventory.data;
}
inventory.itemList.push(coffee);
var updateSingleton = entityProxy.updateSingleton(
entityType,
inventory,
{},
-1
);
if (updateSingleton.status !== 200) {
throw 'Error occured on purchase.';
}
} catch (e) {
productProxy.awardCurrency(currencyType, amount);
}
return inventory;
}
var result = PurchaseCoffee();
result;
En résumé, le script tente d'acheter un café du catalogue et de le placer dans une entité usager représentant son inventaire. Si l'utilisateur n'a pas assez de points, l'achat échoue.
Pour appeler ce script pour notre test unitaire, nous allons créer et appeler un script supplémentaire appelé _Test_PurchaseCoffee.
var currencyType = 'points';
var amount = 4000;
var productProxy = bridge.getProductServiceProxy();
productProxy.awardCurrency(currencyType, amount);
var scriptProxy = bridge.getScriptServiceProxy();
var scriptName = 'PurchaseCoffee';
var jsonScriptData = {
key: 'DARK_ROAST'
};
var testResult = scriptProxy.runScript(scriptName, jsonScriptData);
var testOutput;
try {
if (testResult.data.response.itemList.length === 1) {
testOutput = { passed: true };
} else {
testOutput = {
passed: false,
message:
'Expected 1 item. Found ' +
testResult.data.response.itemList.length
};
}
} catch (e) {
testOutput = { passed: false, message: testResult };
}
if (!testOutput.passed) {
var errorMessage = '_Test_PurchaseCoffee Failure';
bridge.logErrorJson(errorMessage, testOutput);
}
var playerStateProxy = bridge.getPlayerStateServiceProxy();
playerStateProxy.deleteUser();
testOutput;
Notez que dans le script, nous commençons par donner à l'utilisateur final 4000 points pour qu'il puisse exécuter les conditions de test.
Nous appelons ensuite notre PurchaseCoffee avec la clé DARK_ROAST. Si l'utilisateur possède un nouveau compte, le script PurchaseCoffee crée une entité usager pour représenter son inventaire.
Pour garantir le bon fonctionnement du script, nous pouvons vérifier si la taille de l'inventaire retournée est égale à 1. Si un résultat inattendu se produit, nous le journalisons avec logErrorJson.
Enfin, ce script supprime l'usager afin de garantir un nouvel état lors de son prochain appel. Notez cependant que le script ne crée pas d'usager au préalable. Il est impossible de créer de nouveaux profils utilisateur avec un script Cloud ; l'appel à Authenticate doit être effectué avant l'appel au script _Test_PurchaseCoffee.
Nous pouvons ensuite ajouter le test à notre suite d'unités de test et vérifier par rapport à la réponse du cloud code et voir s'il a retourné une valeur transmise égale à true.
it('should successfully pass _Test_PurchaseCoffee', () => {
let _bc = new brainCloud.BrainCloudWrapper('default');
_bc.initialize(APP_ID, APP_SECRET, '1.0.0');
_bc.setStoredProfileId('');
_bc.authenticateAnonymous((authResponse) => {
_bc.script.runScript('_Test_PurchaseCoffee', { key: 'DARK_ROAST' }, (response) => {
expect(response.data.response.passed).to.equal(true)
});
});
}
Bon codage !