TDDs + reutilització d'objectes en Visual Studio 2012

Doncs això, mai m'he mostrat partidari de cap metodologia de programació, ni tan sols de la programació orientada a objectes... però deu ser que em faig major ;) Anem a matar en un post dos pardals d'un tir. Anem a gastar una de les bases de les metodologies àgils (en realitat no té per què, es pot emprar en qualsevol metodologia) i anem a començar a veure com fer codi "multiplataforma".
Anem a gastar Visual Studio 2012. Creem una solució de Portable Class Library (en C#):
Creem una nova classe, Dau:
namespace RollDice
{
    public class Dau
    {

    }
Sense cap mètode. Per què sense cap mètode? Ahí està la gràcia dels TDD (Test Driven Development, Desenvolupament Orientat a Test). Anirem omplint la classe segons fallen els tests.
Ara anem a afegir una nova solució, què serà de test c#:
Ens crearà una classe de test buida, li canviarem el namespace per a que siga el mateix que la classe dau:
[TestClass]
    public class testDau
    {

         [TestMethod]
         public void TestMethod1(){
        }
    }

De moment només ens interessa saber que el mètode que hi haja darrere de cada [TesMethod] Serà un test, ens eixirà a la finestra de tests (després veurem).
Què és el primer que hem de comprovar? Que li fa falta a un dau? El nombre de cares, no? Si no heu jugat a rol, possiblement no ho entendreu ;)
canviem el nom al test, per a que siga més encertat, creem un dau amb 4 cares i comprovem que realment les tinga quan es crea, per a això ens caldrà afegir una variable privada dau:
 private Dau dau;
 [TestMethod]
        public void TestCares()
        {
            dau = new Dau(4);
            Assert.AreEqual(4, dau.getCares);           
        }

Anem a pams, el primer que passa és què això no compila, la classe Dau està buida i no té cap mètode, fem que compile, afegim a la classe dau el constructor i la propietat cares:
 public Dau(int cares)
        {
            getCares = cares;
        }       
        public int getCares {  get; private set; }

 Ara que compila anem a veure que fa el test. Crea un dau de 4 cares, i el test passarà (les condicions de passar el test es fan amb les instruccions Assert) si efectivament el test és de 4 cares.  Seleccionem el menu Test->Run All Test

Si el test passa veurem un check verd, si no passa, veureu una aspa roja,comproveu-ho posant:
  Assert.AreEqual(5, dau.getCares);

Una vegada ja tenim comprovat que el constructor funciona, anem a acabar el dau. Què li falta? Tirar, l'opció de tirar. Abans de programar el codi, recordeu, hem de fer el test; afegim a la classe de test:
 [TestMethod]
        public void TestTirades()
        {
                dau = new Dau(10);
                 int tirada = dau.Tirada();
                Assert.IsTrue(tirada <= 10);
                Assert.IsTrue(tirada >= 1);
          }

      
en este exemple, creem un dau de 10 cares, el llancem, i comprovem que la tirada estiga entre 1 i el nombre de cares. Com no compilarà, creem el mètode a la classe dau:
  public int Tirada()
        {
            Random random = new Random();
            return random.Next(1, getCares);
        }

Vejam que el test passa. Òbviament este test, només serà vàlid per a 10 cares, res ens impedix fer este test:

 [TestMethod]
        public void TestTirades()
        {
          
            for (int i = 1; i <= 20; i++)
            {
                dau = new Dau(i);
                int tirada = dau.Tirada();
                Assert.IsTrue(tirada <= i);
                Assert.IsTrue(tirada >= 1);
            }
        }

 I així hauriem comprovat que els daus, almenys fins a 20 cares, funcionen ;). Doncs això és el TDD, primer realitzar quins tests ha de passar (incloent limits de vectors, entrades extranyes, si llança excepcions...)
A propers posts continuarem el projecte afegint múltiples configuracions per al projecte

Comentaris

  1. Espere que hages llegit "Test-Driven Development by Example (Kent Beck)" o algún d'aquests i t'hages adonat que l'últim fragment de codi que has escrit és una burrada: els tests no han d'incloure lògica (for, while, switch i demés en un test són caca) i els tests només han de testejar una cosa (més d'un Assert per test també és caca)

    Això sí, no em preguntes per què :P

    ResponElimina
  2. Bo, en la pàgina de l'autor de Clean Code, Robert C. Martin, tenen un exemple, d'una partida de bolos on gasten lògica ;-)
    A banda, el tema de múltiples assert es deu a la limitació dels tests. No permet establir límits, comprovar si llança excepcions...
    Tot això no lleva que tingues raó i el codi siga una merda.

    ResponElimina
  3. Més menys per la meitat:
    http://www.objectmentor.com/resources/articles/xpepisode.htm

    public void testPerfectGame()
    {
    for (int i=0; i<12; i++)
    {
    g.add(10);
    }
    assertEquals(300, g.score());
    assertEquals(10, g.getCurrentFrame());
    }

    ResponElimina
  4. Segur que a la pàgina de després diu: "mai feu això a casa, els tests no han d'incloure lògica i més d'un assert"... però no ho has llegit :D

    ResponElimina
  5. Segur, però ja saps... com a bon tertuliano pepero, cite el que em convé, ho descontextualitze i ignore la resta 😉

    ResponElimina

Publica un comentari a l'entrada

Entrades populars d'aquest blog

Clean Code... WTF? És realment viable?

Comparativa dels Sistemes Polítics Espanyol, Valencià i d'un partit polític. (II)

Hui he vist la por als ulls