Tehtävä 1

Scrum määrittelee joukon rooleja, artefakteja, palavereja sekä pelisääntöjä. Kerro mitä keinoja Scrum tarjoaa alla olevien ongelmatilanteiden ratkaisemiseksi. Ei riitä että luettelet vain termejä, kerro mistä kussakin Scrumin tarjoamassa lääkkeessä on kyse, ja miten se auttaa kuvattuun ongelmaan.

  • Silva ja Jussi kiistelevät usein siitä kuuluisiko uusille featureille kirjoittaa yksikkötestejä.
    Aika usein firman markkinointiosaston päällikkö Jami saa briljantteja ideoita ja ne pitää toteuttaa välittömästi, riippumatta siitä mikä on kesken.
  • Turhan usein huomataan että pari kehittäjää, erityisesti Kristian ja Petrus ovat koodanneet kumpikin oman versionsa samasta user storystä. Monen päivän työ saattaa mennä hukkaan.
  • Välillä on epäselvää mitä storyja sprintissä pitäisi tehdä, se riippuu hieman siitä keneltä firman johtajista sattuu kysymään, erityisesti toimari Luukkaisen mielipide poikkeaa muiden managerien linjasta.
  • Projektissa toistuu kuukaudesta toiseen samat ongelmat, esim. gitiä käytetään vähän miten sattuu, testit toimii välillä ja välillä ei. Koodissa luokkien ja metodien nimeäminen on aika randomia.
  • Kallen mielestä on kiva kun saa koodailla ihan rauhassa. Huono puoli on kyllä se, että kukaan ei oikein tiedä millon ylipäätään saadaan jotain valmista aikaan, välillä siihen menee kuukausia.
  • Nää sprintit on kivoja. On vaan hieman kaoottista välillä kun kukaan ei tiedä mitä sprintissä tulisi tehdä, on mysteeri miten eri user storyjen toteuttaminen vaikuttaa olemassa olevaan koodiin.
  • Meillä on vähän ongelmana se, että vaikka usein saadaankin kaikki toteutettua, ei niitä voi sprintin lopussa viedä tuotantoon kun Intiassa sijaitseva testaajatiimi toimii usean viikon viiveellä.

Tehtävä 2

Kaverisi on määritellyt seuraavanlaisen user storyn joka kuvaa verkkokaupan ostosten maksutoiminnallisuuden. Mitä hyvää ja huonoa storyssä on ja mitä siitä puuttuu? Miten storysta saisi paremman?

Kun ostoskorissa olevat tuotteet maksetaan (toimii luottokortin lisäksi MobilePayllä ja muillakin mahollisilla maksuvaihtoehdoilla), pitää tietokannan tauluun ORDERS kirjottaa toimitusosoite. Myös tuotteiden varastosaldoja ylläpitävää taulua PRODUCTS tulee päivittää. Kannattaa huomata, että myynti on hirveä Black Fridayn aikana, softan pitää kuitenkin säilyä nopeana vaikka olisi mieletön käyttäjäpiikki. Kannattaa samantien koodata mahollisuus määritellä miten toimitus järjestetään, postin kautta vai jonkun muun palvelun kuten UPS:n. Tää story pitää toteuttaa heti, tää on elintärkeä.

Tehtävä 3

Ovatko seuraavat väittämät totta vai epätotta?

  • Ohjelmiston validointi tapahtuu yksikkötestauksella
  • Jos käyttäjät ovat tosi tyytyväisiä, on ohjelmiston ulkoinen laatu todennäköisesti kunnossa -
  • Testien riittävä rivikattavuus pystytään varmistamaan tutkivalla testaamisella
  • Burn down -kaavion avulla voidaan arvioida kuinka paljon koodaajilla on vielä työtunteja käytettävissä menossa olevan sprintin aikana
  • Saavutettavuusdirektiivin (https://vm.fi/saavutettavuusdirektiivi) noudattaminen on ns. ei-toiminnallinen vaatimus
  • Jos tehdään ns. minimal viable product, sille ei yleensä tehdä kattavia automatisoituja testejä
  • Velositeetin avulla saattaa olla mahdollista arvioida milloin ohjelmisto tai jokin sen osa valmistuu
  • Myös ketterissä menetelmissä vaatimukset dokumentoidaan
  • Koodikatselmointi on niin vesiputousta, se ei kuulu ketterään ohjelmistokehitykseen
  • Scrum of Scrums on eräs tapa yrittää huolehtia siitä, että firman eri tiimit pystyvät työskentelemään yhteisen päämäärän mukaisesti
  • Inkrementaalinen arkkitehtuuri takaa sen että koodin sisäinen laatu pysyy kunnossa
  • Lean startup -menetelmä kieltää teknisen velan ottamisen

Tehtävä 4

Leanin yhteydessä puhutaan Just in Time (JIT) -tuotannosta, sekä tuotannon sykliajan minimoimisesta.

Kerro mitä hyötyjä lyhyestä sykliajasta on ohjelmistotuotannossa, miten ohjelmistotuotannossa pyritään lyhentämään sykliaikaa ja mitä tekemistä DevOpsilla on asian kanssa.

Vastauksesi tulee myös kertoa mitä käsitteillä Just in Time (JIT) -tuotanto, tuotannon sykliaika sekä DevOps tarkoitetaan.

Tehtävä 5

(a) Mitä tarkoitetaan ohjelmiston sisäisellä laadulla? (1p) (b) Mitä sisäisen laadun kannalta ongelmallisia asioita esimerkkikoodissa on? (3) Selitä miten refaktoroisit alla esimerkkikoodin soveltaen suunnittelumalleja tai muita tilanteeseen sopivia ratkaisuja

public class UserStory {
    private int sprint;
    private String name;
    private int estimate;
    private String status;
    private List<String> tasks;
    public UserStory(String name, int sprint, int estimate, String status, List<String> tasks) {
        this.name = name;
        this.sprint = sprint;
        this.estimate = estimate;
        this.status = status;
        this.tasks = tasks;
    }
    public boolean done(){
       return status.equals("COMPLETED");
    }
    public void changeStatus(String status) {
        this.status = status;
    }
    public int estimate() {
        return estimate;
    }
    public String status() {
        return status;
    }
    public String name() {
        return name;
    }
}

public class BacklogReader {
    private String file;
    public BacklogReader(String file) {
        this.file = file;
    }
    public List<UserStory> readFromFile(){
        List<UserStory> items = new ArrayList<>();
        // read stories from file
        return items;
    }
    public void saveToFile(){
        // save stories to file
    }
}

public class Backlog {
    private List<UserStory> stories;
    private BacklogReader reader;
    public Backlog() {
        reader = new BacklogReader("tmc-cli");
        stories = reader.readFromFile();
    }
    public List<UserStory> completedStories() {
        ArrayList<UserStory> completed = new ArrayList<>();
        for (UserStory story : stories) {
            if ( story.done() ) {
                completed.add(story);
            }
        }
        return completed;
    }
    public List<UserStory> epics() {
        ArrayList<UserStory> epicStories = new ArrayList<>();
        for (UserStory story : stories) {
            if ( story.estimate()>20 ) {
                epicStories.add(story);
            }
        }
        return epicStories;
    }
    public String export(String format, boolean onlyRemaining) {
        String output = "";
        if ( format.equals("xml")){
            output = "<stories>";
        }
        for (UserStory story : stories) {
            if (onlyRemaining && !story.done() ) {
                continue;
            }
            if ( format.equals("text")) {
                output += story.name()+ " " + story.estimate()+ " " + story.status() + "\n";
            } else if ( format.equals("xml"))  {
                output += "<story><name>" + story.name() +
                            "</name><estimate>" + story.estimate() +
                            "</estimate><status>" + story.status() +
                          "</status><story>\n";
            } else {
                throw new IllegalArgumentException("format not supported");
            }
        }
        if ( format.equals("xml")){
            output += "</stories>";
        }
        return output;
    }
    // other methods...
}