diff --git a/src/tests/RenderingTest.java b/src/tests/RenderingTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fd028c256607bb121a345102e4da22283f9c0bf
--- /dev/null
+++ b/src/tests/RenderingTest.java
@@ -0,0 +1,86 @@
+package tests;
+
+import opinion.*;
+
+public class RenderingTest {
+
+    private static void runAddMembers() throws Exception {
+        System.out.println("------------------------------------");
+        Tools.resetCounters();
+        int i = 1000;
+        int max = 10000;
+        ISocialNetwork sn = new SocialNetwork();
+        System.out.println("nbMembersAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, 0, 0, 0);  // avg per op in nanoseconds
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
+
+    private static void runAddBooks() throws Exception {
+        System.out.println("----------------------------------");
+        Tools.resetCounters();
+        int i = 1000;
+        int max = 10000;
+        ISocialNetwork sn = new SocialNetwork();
+        System.out.println("nbBooksAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, i, 0, 0);
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
+
+    private static void runAddFilms() throws Exception {
+        System.out.println("----------------------------------");
+        Tools.resetCounters();
+        int i = 1000;
+        int max = 10000;
+        ISocialNetwork sn = new SocialNetwork();
+        System.out.println("nbFilmsAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, 0, i, 0);
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
+
+    private static void runAddReviews() throws Exception {
+        System.out.println("------------------------------------");
+        int i = 1000;
+        int max = 10000;
+        System.out.println("nbReviewsAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            ISocialNetwork sn = new SocialNetwork();
+            Tools.resetCounters();
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, 10, 10, i);
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
+
+    public static void main(String[] args) {
+        try {
+            runAddMembers();
+            runAddBooks();
+            runAddFilms();
+            runAddReviews();
+        } catch (Exception e) {
+            System.out.println("Error : " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/tests/ReviewItemBookTest.java b/src/tests/ReviewItemBookTest.java
index 327b417d8241a061f92dcf11733231a18af95fef..4eb6b482e065b6722d7f33d27069b798de3f441a 100644
--- a/src/tests/ReviewItemBookTest.java
+++ b/src/tests/ReviewItemBookTest.java
@@ -125,15 +125,15 @@ public class ReviewItemBookTest {
 
         // Nominal cases
 
-        // Test 3.1 : First review for "El Hobbit", expects average mark of 4.0
+        // Test 3.8 : First review for "El Hobbit", expects average mark of 4.0
         nbTests++;
         nbErrors += checkReviewItemBookAverage(sn, "Neva", "pass123", "El Hobbit", 4.0f, "So good", 4.0f, "3.8");
 
-        // Test 3.2 : Second review from another user, expects average of (4.0 + 5.0) ÷ 2 = 4.5
+        // Test 3.9 : Second review from another user, expects average of (4.0 + 5.0) ÷ 2 = 4.5
         nbTests++;
         nbErrors += checkReviewItemBookAverage(sn, "Maryam", "1234pass", "El Hobbit", 5.0f, "Perfect", 4.5f, "3.9");
 
-        // Test 3.3: Update Neva's review to 3.0, expects average of (3.0 + 5.0) ÷ 2 = 4.0
+        // Test 3.10: Update Neva's review to 3.0, expects average of (3.0 + 5.0) ÷ 2 = 4.0
         nbTests++;
         nbErrors += checkReviewItemBookAverage(sn, "Neva", "pass123", "El Hobbit", 3.0f, "Good but too long", 4.0f, "3.11");
 
diff --git a/src/tests/Tools.java b/src/tests/Tools.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f34ef35620c5cfe2826574feb33f50af797dae7
--- /dev/null
+++ b/src/tests/Tools.java
@@ -0,0 +1,214 @@
+package tests;
+
+import opinion.ISocialNetwork;
+import exceptions.*;
+
+/**
+ * Tools for testing a ISocialNetwork
+ * @author cousin
+ *
+ */
+public class Tools {
+
+    private static java.util.Random randomGenerator;
+
+    /*
+     * These counters allow specific members/books/films to be automatically generated, through String concatenate operations
+     * There are static, so as to guarantee that successive calls to populate() won't generate identical Strings
+     * They represent the number of members/books/films already generated via Tools
+     * but depending on other actions made on the ISocialNetwork, they may differ from its actual 'numbers' of members/books/films
+     */
+    private static int nextMember = 1; // next value for members (cf logins/passwords)
+    private static int nextBook = 1;   // next value for books (cf title)
+    private static int nextFilm = 1;   // next value for films (cf title)
+
+    /*
+     * These constants are String or prefix-String to be used when generating new members/books/films/reviews
+     */
+    private static final String LOGIN ="member";
+    private static final String PASSWORD = "passwd";
+    private static final String PROFILE ="profile";
+
+    private static final String TITLE = "title";
+    private static final String KIND = "kind";
+    private static final String AUTHOR = "author";
+    private static final int NB_PAGES = 12;
+
+    private static final String DIRECTOR = "director";
+    private static final String SCENARIST = "scenarist";
+    private static final int DURATION = 15;
+
+    private static final String COMMENT = "comment";
+
+    /**
+     * Resets the counter for number of members, books and films.
+     */
+    public static void resetCounters() {
+        nextMember = 1;
+        nextBook = 1;
+        nextFilm = 1;
+    }
+
+    /**
+     * Adds members, books, films and reviews to the ISocialNetwork, according to the following process :<br>
+     * 1. Adds the asked number of members, giving them pseudo-random logins/passwords<br>
+     * 2. Make one of the added members to add the total asked number of books, giving them pseudo-random characteristics<br>
+     * 3. Make one of the added members to add the total asked number of films, giving them pseudo-random characteristics<br>
+     * 4. Add the asked number of reviews : <br>
+     *    - reviewed items (book/film) and reviews'authors are randomly chosen among those that were added by Tools<br>
+     *    - depending on "chance", a member can add a review on an item that he already had reviewed, which will replace this previous review. It is therefore not guaranteed that the total number of reviews stored in the ISocialNetwork will have a nbReviews increase.<br>
+     * @param sn the ISocialNetwork to work with
+     * @param nbMembers the number of members to add to sn.
+     * @param nbBooks the number of books to add to sn
+     * @param nbFilms the number of films to add to sn
+     * @param nbReviews the number of reviews to add to sn
+     * @return meantime of each operation
+     * @throws java.lang.Exception whenever one of the calls to addMember(), addItemBook(), addItemFilm(), reviewItemBook() or reviewItemFilm() throws an exception, this exception is directly rethrown to the caller. That's why these methods should have been well tested before trying to use populate().
+     **/
+    public static long populate (ISocialNetwork sn, int nbMembers, int nbBooks, int nbFilms, int nbReviews)
+            throws BadEntryException, MemberAlreadyExistsException, NotMemberException, ItemBookAlreadyExistsException, ItemFilmAlreadyExistsException,  NotItemException {
+
+        long elapsedTime=0;
+        long before, after; //timestamps
+        int totalNbOfOperations = nbMembers + nbBooks +nbFilms + nbReviews;
+        randomGenerator = new java.util.Random();
+
+        //
+        // Adds nbNumber members, giving them pseudo-random logins/passwords
+        //
+        for (int i=0; i<nbMembers;i++) {
+            before = System.nanoTime();
+            sn.addMember(LOGIN+nextMember, PASSWORD+nextMember, PROFILE);
+            after = System.nanoTime();
+            elapsedTime += after - before;
+            nextMember++;
+        }
+
+        //
+        //  Make the last added member to add the total asked number of books, giving them pseudo-random characteristics
+        //
+        if (nbBooks>0) {
+            //we don't care about WHO adds the books, so we only use last added member to do it
+            if (nextMember==1) throw new BadEntryException ("populate() : must add at least a member before being able to add books");
+            for (int i=0;i<nbBooks;i++) {
+                int lastMemberNumber = nextMember-1;
+                before = System.nanoTime();
+                sn.addItemBook(LOGIN+lastMemberNumber, PASSWORD+lastMemberNumber, TITLE+nextBook, KIND, AUTHOR, NB_PAGES);
+                after = System.nanoTime();
+                elapsedTime += after - before;
+                nextBook++;
+            }
+        }
+
+        //
+        // Make one of the added members to add the total asked number of films, giving them pseudo-random characteristics
+        //
+        if (nbFilms>0) {
+            // we don't care about WHO adds the films, so we only use last added member to do it
+            if (nextMember==1) throw new BadEntryException ("populate(): must add at least 1 member before being able to add films");
+            for (int i=0;i<nbFilms;i++) {
+                int lastMemberNumber = nextMember-1;
+                before = System.nanoTime();
+                sn.addItemFilm(LOGIN+lastMemberNumber, PASSWORD+lastMemberNumber, TITLE+nextFilm, KIND, DIRECTOR, SCENARIST, DURATION);
+                after = System.nanoTime();
+                elapsedTime += after - before;
+                nextFilm++;
+            }
+        }
+
+        //
+        //  Add the asked number of reviews :
+        //    - author of each review is randomly chosen among those that were added in step 1 ;
+        //    - reviewed items (book/film) and reviews'authors are randomly chosen among those that were added in steps 1, 2 and 3
+        //    - depending on "chance", a member can add a review on an item that he already had reviewed, which will replace this previous review.
+        //  It is therefore not guaranteed that the total number of reviews stored in the ISocialNetwork will have a nbReviews increase.
+        //
+        if (nbReviews>0) {
+            // try to fairly distribute reviews over members that were generated this time and previously
+            // try to fairly distribute reviews among items
+
+            if (nextMember==1) throw new BadEntryException ("populate() : must add at least a member before being able to add reviews");
+            if ((nextBook==1)&&(nextFilm==1)) throw new BadEntryException ("populate() : must add at least an item before being able to add reviews");
+            int currentMemberNum; // number of the member that do the review
+            int itemNum; // number of the item that is reviewed
+
+            // reviews will be splited between books reviews and film reviews
+            int nbBookReviews, nbFilmReviews; // number of book reviews  and film reviews
+            nbBookReviews = nextBook * (nbReviews / (nextBook + nextFilm)) ; // proportional distribution
+            nbFilmReviews = nbReviews - nbBookReviews;
+
+            currentMemberNum = nextMember-1; // work downward so as to have new members contribute first
+
+
+            for (int i = 0; i<nbBookReviews;i++) {// add a book review
+//                itemNum = 1 + randomGenerator.nextInt(nextBook-2); // choose randomly a book to review - some tricks here, dealing with boundaries
+                int max = Math.max(1, nextBook - 2);  // ensure bound is at least 1
+                itemNum = 1 + randomGenerator.nextInt(max);
+
+                before = System.nanoTime();
+                sn.reviewItemBook(LOGIN+currentMemberNum, PASSWORD+currentMemberNum, TITLE+itemNum, 5*randomGenerator.nextFloat(), COMMENT);
+                currentMemberNum = (currentMemberNum>1)  ? currentMemberNum-1 : nextMember-1; // decrementing modulo nextMember
+                after = System.nanoTime();
+                elapsedTime += after - before;
+                nbReviews--;
+            }
+
+            for (int i = 0; i<nbFilmReviews;i++) {// add a film review
+//                itemNum = 1 + randomGenerator.nextInt(nextFilm-2); // choose randomly a film to review - some tricks here, dealing with boundaries
+                int max = Math.max(1, nextFilm - 2);
+                itemNum = 1 + randomGenerator.nextInt(max);
+
+                before = System.nanoTime();
+                sn.reviewItemFilm(LOGIN+currentMemberNum, PASSWORD+currentMemberNum, TITLE+itemNum, 5*randomGenerator.nextFloat(), COMMENT);
+                currentMemberNum = (currentMemberNum>1)  ? currentMemberNum-1 : nextMember-1; // decrementing modulo nextMember
+                after = System.nanoTime();
+                elapsedTime += after - before;
+                nbReviews--;
+            }
+        }
+
+        return elapsedTime/totalNbOfOperations;
+
+    }
+
+    /**
+     * Verifies if the SocialNetwork prototype can handle 500 members and 5000 items within 2 seconds.
+     * Verifies if disk space has ≤ 10 GB + 1 GB per 1000 users/items
+     */
+    public static void testPerformancePrototype() {
+        ISocialNetwork sn = new opinion.SocialNetwork();
+        resetCounters();
+
+        int nbMembers = 500;
+        int nbBooks = 2500;
+        int nbFilms = 2500;
+        int nbReviews = 1000;
+
+        try {
+            long before = System.nanoTime();
+            long avgNano = populate(sn, nbMembers, nbBooks, nbFilms, nbReviews);
+            long after = System.nanoTime();
+
+            double totalMillis = (after - before) / 1_000_000.0;
+            double avgMillis = avgNano / 1_000_000.0;
+
+            int totalStorage = (int) Math.ceil(nbMembers / 1000.0 + (nbBooks + nbFilms) / 1000.0) + 10; // Disk space: base 10GB + 1GB per 1000 members and 1000 items
+
+            System.out.println("Prototype Performance Test");
+            System.out.printf("Total members: %d\n", nbMembers);
+            System.out.printf("Total items: %d (%d books & %d films)\n", nbBooks + nbFilms, nbBooks, nbFilms);
+            System.out.printf("Total reviews: %d\n", nbReviews);
+            System.out.printf("Total execution time: %.3f ms\n", totalMillis);
+            System.out.printf("Average operation time: %.6f ms\n", avgMillis);
+            System.out.printf("Meets time requirement: %s\n", totalMillis <= 2000 ? "YES" : "NO");
+            System.out.printf("Estimated disk space required: %d GB\n", totalStorage);
+        } catch (Exception e) {
+            System.out.println("Error : " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        Tools.testPerformancePrototype();
+    }
+}
\ No newline at end of file