Cronometro - nao vejo problema em ser separado - outro programa. É flexível e funciona muito bem.

granularidade de salvar arquivo  = quanto mais recente, maior frequencia de alterações ( critério do google docs)
haverá mais utilidade e consultas se:
Como não devem ser alteradas as regras do Dojo, será interessante criar atividade, nao necessariamnete presencial, que de continuidade na solução. Teríamos então aprendizagem em
Saída desejada do ambiente de teste quando for retornado valor diferente do esperado
chamadas para teste

def teste_select_tabela_project_com_coluna_name(self):
    sql = Sql()
    table_name = "project"
    columns = ["name"]
    entradas = '
    obtido = sql.select(table_name, columns)
    teste ('teste_select_tabela_project_com_coluna_name', 'table_name, columns', 'SELECT name FROM project', obtido)


function teste(titulo, entradas, esperado, obtido)
titulo=???
entrada=w,wr,rrr,tewet,
esperado='kkkhkhkhkkh'
obtido=fun(entrada)

  def teste_select_tabela_project_com_coluna_name(self):
        sql = Sql()
        table_name = "project"
        columns = ["name"]
        self.assertEqual('SELECT name FROM project',
                          sql.select(table_name, columns))

self.assertEqual(esperado, obtido, '%s ================================================== %s===(entradas)\n %s===(saída esperada) \n%s===(saída obtida)\n' % (titulo, entradas, esperado, obtido))


Título do teste7 =====================================================================
entrada1, entrada2 ... entradaN===(entradas)
P-987UYH76IRGJTYTGBHYNUYHJF===(saída esperada)
P-987UYH76IRGJTYTGBHYNUYH===(saída obtida)
Título do teste9 =====================================================================
entrada1, entrada2 ... entradaN==(entradas)
suynwryunimei,oyooyoutio,utp.puop.pp===(saída esperada)
suynwryunimei,oyooyoutio,utp.puop.pp´k,,===(saída obtida)

Exemplo Saldo de Gols
gols a favor, gols contra===nome dos campos de entrada
saldo de gols igual a 2===============================================
7, 5===(entradas)
2===(saída esperada)
3===(saída obtida)
saldo de gols igual a 3===============================================
4, 1===(entradas)
3===(saída esperada)
4===(saída obtida)

OBS: nome dos campos de entrada é opcional
--------------------------------------------------------------------------------------------
Exemplo do SQL
teste_ select_tabela_project_com_coluna_name===============================================
table_name=project, columns = ["name"]===(entradas)
SELECT name FROM project===(saída esperada)
SELECT FROM project===(saída obtida)
teste_ select_tabela_com_uma_coluna===============================================
table_name = "abacaxi", columns = ["description"]===(entradas)
SELECT description FROM abacaxi===(saída esperada)
SELECT description FROM===(saída obtida)
teste_ select_tabela_com_duas_colunas===============================================
table_name = "project", columns = ["description", "whatever"]===(entradas)
SELECT description, whatever FROM project===(saída esperada)
SELECT description FROM project ===(saída obtida)
teste_ select_tabela_com_varias_colunas===============================================
table_name = "project", columns = ["description","whatever","forever","never","whenever"]===(entradas)
SELECT description, whatever, forever, never, whenever FROM project===(saída esperada)
SELECT description, whatever FROM project ===(saída obtida)
teste_ insert_valor_na_tabela_project_com_a_coluna_whatever===============================================
table_name = "project", columns = ["whatever"], values = ["never"]===(entradas)
INSERT INTO project (whatever) VALUES("never")===(saída esperada)
INSERT INTO project () VALUES("") ===(saída obtida)
teste_ insert_valor_em_uma_tabela_qualquer_com_uma_coluna===============================================
table_name = "abacaxi", columns = ["description"], values = ["é uma fruta"]===(entradas)
INSERT INTO abacaxi (description) VALUES("é uma fruta")===(saída esperada)
INSERT INTO (description) VALUES("") ===(saída obtida)
teste_ insert_valores_em_uma_tabela_qualquer_com_varias_colunas===============================================
table_name = "fruta", columns = ["name", "description"], values = ["abacaxi", "é uma fruta"]===(entradas)
INSERT INTO fruta (name, description) VALUES("abacaxi", "é uma fruta")===(saída esperada)
INSERT INTO fruta (name) VALUES("abacaxi") ===(saída obtida)
teste_ insert_valores_em_uma_tabela_com_varias_colunas_e_nr_valores_diferentes===============================================
table_name = "fruta", columns = ["name", "description"], values = ["abacaxi"]===(entradas)
ListasDiferentesException===(saída esperada)
===(saída obtida)

---------------------------------------------------------------------------------
class TestesGeradorSql(unittest.TestCase):

    def teste_select_tabela_project_com_coluna_name(self):
        sql = Sql()
        table_name = "project"
        columns = ["name"]
        self.assertEqual('SELECT name FROM project',
                          sql.select(table_name, columns))

    def teste_select_tabela_com_uma_coluna(self):
        sql = Sql()
        table_name = "abacaxi"
        columns = ["description"]
        self.assertEqual('SELECT description FROM abacaxi',
                          sql.select(table_name, columns))
   
    def teste_select_tabela_com_duas_colunas(self):
        sql = Sql()
        table_name = "project"
        columns = ["description", "whatever"]
        self.assertEqual('SELECT description, whatever FROM project',
                          sql.select(table_name, columns))

def teste_select_tabela_com_varias_colunas(self):
        sql = Sql()
        table_name = "project"
        columns = ["description",
                   "whatever",
                   "forever",
                   "never",
                   "whenever"]
        self.assertEqual('SELECT description, whatever, forever, never, whenever FROM project',
                          sql.select(table_name, columns))

    def teste_insert_valor_na_tabela_project_com_a_coluna_whatever(self):
        sql = Sql()
        table_name = "project"
        columns = ["whatever"]
        values = ["never"]
        self.assertEqual('INSERT INTO project (whatever) VALUES("never")',
                        sql.insert(table_name, columns, values))
    
    def teste_insert_valor_em_uma_tabela_qualquer_com_uma_coluna(self):
        sql = Sql()
        table_name = "abacaxi"
        columns = ["description"]
        values = ["é uma fruta"]
        self.assertEqual('INSERT INTO abacaxi (description) VALUES("é uma fruta")',
                        sql.insert(table_name, columns, values))
              
    def teste_insert_valores_em_uma_tabela_qualquer_com_varias_colunas(self):
        sql = Sql()
        table_name = "fruta"
        columns = ["name", "description"]
        values = ["abacaxi", "é uma fruta"]
        self.assertEqual('INSERT INTO fruta (name, description) VALUES("abacaxi", "é uma fruta")',
                        sql.insert(table_name, columns, values))
   
    def teste_insert_valores_em_uma_tabela_com_varias_colunas_e_nr_valores_diferentes(self):
        sql = Sql()
        table_name = "fruta"
        columns = ["name", "description"]
        values = ["abacaxi"]
        self.assertRaises(ListasDiferentesException, sql.insert(table_name, columns, values))
    
unittest.main()