OXID Modul-Zertifizierung Bedingungen © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 Copyright Copyright © 2012 OXID eSales AG, Deutschland Die Vervielfältigung dieses Dokuments oder Teilen davon, insbesondere die Verwendung von Texten oder Textteilen bedarf der ausdrücklichen vorherigen Zustimmung der OXID eSales AG. Eine Dekompilierung des Quellcodes, unerlaubte Vervielfältigung sowie die Weitergabe an Dritte ist nicht gestattet. Zuwiderhandlungen werden ausnahmslos zur Anzeige gebracht und strafrechtlich verfolgt. Die alleinigen Rechte an der Software sowie an diesem Dokument liegen ausschließlich bei der OXID eSales AG. Die in diesem Dokument bereit gestellten Informationen wurden nach aktuellem Stand der Technik verfasst. Die OXID eSales AG übernimmt jedoch keine Haftung oder Garantie für die Aktualität, Richtigkeit und Vollständigkeit der bereit gestellten Informationen. Da sich Fehler, trotz aller Bemühungen nie vollständig vermeiden lassen, sind wir für Hinweise jederzeit dankbar. Konventionen In diesem Dokument werden die folgenden typographischen Konventionen verwendet: Kursive Schrift wird für Dateinamen, Pfadangaben, E-Mail-Adressen und URLs verwendet. Nichtproportionalschrift wird für Codebeispiele und Namen von Codeelementen verwendet. Nichtproportionalschrift kursiv wird für Navigationsschritte verwendet. Impressum OXID eSales AG Bertoldstraße 48 79098 Freiburg Deutschland Fon: +49 (761) 36889 0 Fax: +49 (761) 36889 29 Vorstand: Roland Fesenmayr (Vorstandsvorsitzender), Eric Jankowfsky, Andrea Seeger Sitz: Freiburg Amtsgericht Freiburg i. Brg. HRB 701648 © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 2/10 Rules for OXID eShop Module Certification This list contains all conditions for developing certificable eShop modules for eShop versions above 4.0. The document contains all conditions for certification and shall provide a quick overview. Details to the single issues will be communicated in the offered trainings and are noted in the trainingsmaterials respectivly. Category Policy fullfilled? Softwaretests 1.1 1 testclass per module class 1.2 Class Unit_MODULKLASSETest extends OxidTextCase 1.3 at least 1 test per method 1.4 demonstrative & destructive tests 1.5 NO assertTrue(true) 1.6 atomic tests 1.7 MODULNAMETest.php for automatic execution of all tests 1.8 code coverage > 90% 1.9 minimal disturbance of the eShop tests Softwarequality 2.1 no globals * 2.2 no global functions * 2.3 no business logic in smarty funktions 2.4 PHP5 Code 2.5 oxSuperCfg 2.6 getter & setter 2.7 oxExceptions 2.8 maximum length of methods < 80 lines (< 40 Best Practice) * 2.9 maximum NPath complexity < 200 * 2.10 maximum cyclomatic complexity = 4 * 2.11 maximum C.R.A.P. index < 30 * intermodul compatibility 3.1 prefix before datenbase field names 3.2 prefix before table names 3.3 prefix before config parameters 3.4 prefix before language constants 3.5 ::parent call * 3.6 oxNew * © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 3/10 dokumentation 4.1 Readme.txt 4.2 Install.sql 4.3 Changelog.txt 4.4 PHPDoc (@extend, …) 4.5 folder copy_this 4.6 folder change_full 4.7 folder Documentation 4.8 changes in templates marked by (MODULNAME BEGIN – MODULNAME END) 4.9 good comments !!! (see example comments) * Variations could be allowed in justified cases. 1. Remarks to Softwaretests 1.1. 1.2. Per modul class there should be a test class und each class should be stored in a separate file* Naming conventions for test classes: Class Unit_MODULKLASSETest extends OxidTextCase and testmethods: testMethodename() so it is clear which testMethod tests which method 1.3. For each method there should be at least one test in the testMethod respectively. Hint: you should have NPath complexity number of tests in the testMethod 1.4. You should test for correct working of a method as well as for failure cases and for edge cases. (what happens on the edge of the domain?) What happens with correct input? What happens with incorrect input? What happens in edge case? 1.5. Do not test for conditions which are fullfilled anyway - NO „assertTrue(true)“ 1.6. Each method should be tested on its own. There shouldn’t be any dependencies between the tests. If there are use stubs and dependency injection. See PHPUnit Manual - Mocking 1.7. Write a main class MODULNAMETest.php to run all tests at once. Shop tests AND module tests should run together!!! As an example for MODULNAMETest.php see AlltTestsUnit.php © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 4/10 1.8. The code coverage has to be greater than 90%. This means the code coverage for Lines of Code (LOC) 1.9. Your unit tests should interfere as least as possible with the shop tests. If you run all tests at once (eShop-Unittests + Modul-Unittests) no shop test should fail. 2. Remarks to the category software quality 2.1. Avoid the use of global variables. 2.2. Avoid the use of global functions. 2.3. Use smarty only for design purposes. Business logic belongs to the PHP-Level. 2.4. Do object orientated programming. 2.5. ???oxSuperCfg – um modulspezifische Parameter zu setzen und abzurufen ist die Klasse oxSuperCfg abzuleiten (z. Bsp. speichern von Variablen in einer Session etc. ) 2.6. The access of public variables of class should be realised via getter and setter methods. 2.7. Use oxException to derive from to create your own exception classes. 2.8. The number of lines of a method shouldn’t be higher than 80*. Best practise is below 40. And we will reject modules containing methods with more than 120 lines of code. 2.9. The NPath complexity is the number of possible execution paths throug a method. Each control structure (e. g. if, elseif, for, while, case,...) is taken into account also the nested and multipart boolean expressions. It should be lower than 200 and module will not be certified if it is above 500. 2.10. The cyclomatic complexity is measured by the number of if, while, do, for, ?:, catch, switch, case statements, and operators && and || (plus one) in the body of a constructor, method, static initializer, or instance initializer. It is a measure of the minimum number of possible paths through the source and therefore the number of required tests. Generally 1-4 is considered good, 5-7 ok, 8-10 consider re-factoring, and 11+ re-factor now. A hard limit is a ccn of 8. 2.11. Change Risk Analysis and Predictions (C.R.A.P.) index of a function or method uses cyclomatic complexity and code coverage from automated tests to help estimate the effort and risk associated with maintaining legacy code. A CRAP index over 30 will not be accepted. © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 5/10 3. Remarks to the category intermodul compatibility General: The Prefix should be used consistently and it should be registered at Oxid. Therefore the prefix should be the first part of the name of your 4. 3.1. data base field 3.2. data base table 3.3. config parameters 3.4. language constants 3.5. If you extend a method you should always call the parent method via parent::Methoden name z 3.6. For creating objects always use the oxNew() function. Remarks to the category documentation 4.1. in Readme.txt there should be the following informations : • Title – the name of the module • Author – the author/company of the module • Prefix – the prefix you use • Version – version of the module which is described • Link – a link to the homepage of the author/company • Mail – email for contact • Description – a short description of the function of the module • Extend – which classes and methods are extended • Installation – a detailed description how to install the module • Modules – which other modules are used • Libraries – which libraries are used • Resources – other resources © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 6/10 Beispiel Readme.txt ==Title== Example module ==Author== Der Autor ==Prefix== pref ==Version== 0.1.0 ==Link== http://some link ==Mail== [email protected] ==Description== A description ==Extend== *someClass --some method ==Installation== do something 4.2. A file which contains SQL statements to alter the data base should be named install.sql and has to be explained in the documentation 4.3. The file changelog.txt should have the following form: ==0.1.0== * Initial release of module. ==0.2.0== * some changes * some bugfixes © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 7/10 that means version numbers are surrounded by „==“, where the newest number is on top of the file and each entry of a version starts with a „*“ 4.4. optional: a html document which was created with PHPDoc using the comments of the source code 4.5. A folder „copy_this“ which will be copied in the root directory of the shop -> see example file Ordnerstruktur.txt 4.6. A folder „change_full“ which will be copied into the template directory -> see example file ordnerstruktur.txt 4.7. optional: a folder „doc“ which contains the html documentation created with PHPDoc and further documentation -> see example file ordnerstruktur.txt 4.8. Changes in Templates should be marked to make more easy to find them. [{* MODULNAME BEGIN *}] . . . [{* MODULNAME END *}] © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 8/10 Example ordnerstruktur example/ +-- readme.txt +-- src ¦ +-- changed_full ¦ ¦ ¦ ¦ +-- azure ¦ ¦ +-- basic ¦ +-- Changelog.txt ¦ +-- copy_this ¦ ¦ +-- admin ¦ ¦ +-- core ¦ ¦ +-- modules ¦ ¦ ¦ ¦ ¦ +-- out ¦ ¦ ¦ ¦ ¦ ¦ +-- de ¦ ¦ ¦ +-- en ¦ ¦ ¦ +-- tpl ¦ ¦ +-- views ¦ +-- docs (optional) ¦ ¦ +-- documentation.html ¦ +-- user_comments.php ¦ ¦ +-- out +--Module +-- admin \-- Install.sql (optional) ¦ +-- tests +--ModulnameTest.php ( Testsuite ) +-- unit +-- modules +--Module ( put the test files here in ) © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 9/10 4.9. ‘Good comments’ means that for each class variable, method and class you should write a comment. A comment should give additional information and not only repeat the name. (see example) example: <?php /** * Cupboard * * @package Furniture * @version $Revision$ * @author * @copyright Copyright (C) 1812 2012 Somecompany . All rights reserved. * @license http://www.gnu.org/licenses/gpl-3.0.txt GPL * @extend oxBaseClass */ class Cupboard extends Cupboard_parent { /** * Number of cups in the cupboard. Declared in units * * @var int */ protected $numberOfCups; /** * Take a cup from cupboard * * Reduces the amount of cups by the specified amount. If * there are not enough cups left the cupboard is emptied. The actual amount * of cups removed from the cupboard will be returned. * * @extend drink * @param int $amount * @return int */ public function take( $amount ) { // inline comment $this->numberOfCups -= $amount = max( $this->numberOfCups, $amount ); return $amount; } © OXID eSales AG | www.oxid-esales.com | [email protected] | Version 1.0.0 10/10